読者です 読者をやめる 読者になる 読者になる

ブログ用の高圧縮(低品質)、Exifなし画像を生成する

 最近は携帯電話のカメラ画質がよくなって、iPhoneとかで撮った画像ってそのままだと3MB〜5MBくらいあります。結構重いですよね。さらに、位置情報などのExif情報が’ついたままブログやSNSにアップロードするのはセキュリティ上好ましくありません。*1

 印刷・デザイン・Web関係者だったら、手持ちのPhotoshopを使ってこういう処理をするためのドロップレットとかを作れますよね。じゃあ、Photoshopをもっていない人はどうすればいいの? GIMPとかでひとつづつチマチマ再保存するしかないんでしょうか?

 今回はImageMagickAppleScriptを使って、ドラッグ&ドロップするだけで画像の再圧縮とExif削除をさせてみたいと思います。原理としては

$ convert -quality 20 -strip orginal.jpg new.jpg

みたいな感じのコマンドをドラッグ&ドロップでできるようにAppleScriptで包みました。*2

 このままでもいいんですが、もうひと工夫。はてなブログは専用のメールアドレスに添付ファイルとして送るとFotolifeにアップロードできます*3。生成した画像をMail.appで送るところまでやってみました。最初のsend_toにメールアドレスを書き込めば添付ファイルにしてくれます。

(*
MakeBlogImage.app
ドラッグ&ドロップで、ブログ用の低クオリティexif無し画像を生成する
要:ImageMagick
具体的にはImageMagickで
convert -quality 20 -strip orginal.jpg new.jpg
を実行する感じ。
メールアドレスを設定すれば、生成画像をそこへ送りつける。(はてなブログのFotolifeでメールアップロード)


2017-02-15	macOS Sierra(10.12.3)とりあえず
*)


--ドラッグ&ドロップで実行
on open of drop_files
	--設定
	set imagemagick_path to "/usr/local/bin/convert" --convertコマンドのフルパス
	set my_quality to "20" --クオリティ(1-100)
	set other_option to "" --その他オプション(最後はスペースを入れること)
	set send_to to "" --送り先メールアドレスが書かれていれば、Mail.appを使って生成した画像を送る(主にはてな用)
	set send_from to "" --Mail.appに設定してある送り主のメールアドレス(意味のない文字列の場合、最初に設定されているメールアドレスが使われる)
	set attachmentFile_list to {} --初期化してるだけ
	
	--ImageMagickがインストールされているかどうか
	try
		do shell script imagemagick_path & " --version"
	on error errMsg number errNo
		display dialog "ImageMagickがインストールされていません" & return & errMsg & return & errNo buttons {"キャンセル"} default button 1 with icon 1 --キャンセルで終了
	end try
	
	--ファイルのフィルタリング(特定の拡張子を持ったファイルだけを処理)
	set my_files to my file_kind({"jpg", "jpeg", "png"}, drop_files) --拡張子のリスト、処理ファイル	
	set save_folder to choose folder with prompt "保存先フォルダを選んでください"
	
	repeat with i in my_files
		my violation_name(i as alias)
		set path_info to my split_path(i as alias)
		set org_path to POSIX path of (i as alias)
		set new_path to (POSIX path of save_folder) & (name_ext of path_info)
		if org_path is new_path then
			display dialog "同じフォルダには上書き保存できません。" buttons {"キャンセル"} default button 1 with icon 1 --キャンセルで終了
		end if
		my alert_same_name(new_path)
		
		--画像生成
		try
			do shell script imagemagick_path & " -quality " & my_quality & " -strip " & other_option & (quoted form of org_path) & " " & (quoted form of new_path) --実行
		on error errMsg number errNo
			display dialog "実行エラーです" & return & errMsg & return & errNo buttons {"キャンセル"} default button 1 with icon 1 --キャンセルで終了
		end try
		tell application "Finder"
			set end of attachmentFile_list to new_path
		end tell		
	end repeat
	
	--メール送信
	--はてなFotolifeは連続2通までしか受信できないっぽい
	if send_to is not "" then
		set my_subject to (do shell script "date '+%Y-%m-%d-%H%M'") --現在の日時をsubjectにしてる
		set my_body to ""
		my send_mail(send_to, send_from, my_subject, my_body, attachmentFile_list)
	end if
	
	
	--終了の合図
	tell application "Finder"
		activate
		display dialog ((count my_files) as Unicode text) & "個のファイルを処理しました。" buttons {"OK"} default button 1
	end tell
end open


----------------------------------------------●必要なファイルだけをフィルタして返します
to file_kind(extention_list, theFiles)
	set my_files to {}
	
	ignoring case
		tell application "Finder"
			repeat with i in theFiles
				if extention_list contains ((name extension of i) as Unicode text) then
					set end of my_files to contents of i
				else if (kind of i) is "フォルダ" as Unicode text then
					--activate
					--display dialog "フォルダ「" & (name of i) & "」の中の全ファイルを処理します" buttons {"キャンセル", "OK"} default button 2 with icon 0
					set my_files to my_files & my file_kind(extention_list, every file in folder i)
				else
					--activate
					--display dialog "ファイル「" & (name of i) & "」は処理ファイルとして不適当です" buttons {"キャンセル", "OK"} default button 2 with icon 0
				end if
			end repeat
		end tell
	end ignoring
	return my_files
end file_kind

----------------------------------------------●
--フルパス名を、コンテナディレクトリ・ファイル名+拡張子・ファイル名・拡張子に分割する
--返値はPOSIX pathのレコード {dir:"", name_ext:"", f_name:"", ext:""}
to split_path(f)
	set f to quoted form of ((POSIX path of f) as Unicode text) --まずPOSIX pathにする
	set d to do shell script "echo " & f & " | perl -pe 's/^(.+\\/).+$/$1/;'" --コンテナディレクトリ
	set ne to do shell script "echo " & f & " | perl -pe 's/^.+\\/(.)/$1/;'" --ファイル名+拡張子
	if f ends with "/'" then --フォルダの場合
		set n to text 1 thru -2 of ne
		set e to ""
	else
		set e to do shell script "echo '" & ne & "' | perl -pe 's/^.+(\\..+)$/$1/;'"
		if e is not "" then
			set n to do shell script "echo '" & ne & "' | perl -pe 's/" & e & "$//;'"
		end if
	end if
	
	return {dir:d, name_ext:ne, f_name:n, ext:e}
end split_path

----------------------------------------------●
--同名ファイルの警告
to alert_same_name(file_path)
	tell application "Finder"
		if (exists (file_path as POSIX file)) then
			display dialog file_path & " は同名のファイルがあります" & return & "上書きしますか?" buttons {"キャンセル", "上書き"} default button 1 with icon 1 --キャンセルで終了
		end if
	end tell
end alert_same_name

----------------------------------------------●
--ファイル名の警告
to violation_name(file_path)
	set file_path to quoted form of ((POSIX path of file_path) as Unicode text) --まずPOSIX pathにする
	set file_path_test to do shell script "echo " & file_path & " | perl -pe 's/[\\/\\.0-9A-Za-z _-]+//;'"
	if (file_path_test is not "") then
		display dialog file_path & " のファイルパスに英数字以外の文字が使われています。" & return & "処理トラブルになるかもしれません。続行しますか?" buttons {"キャンセル", "続行"} default button 1 with icon 1 --キャンセルで終了
	end if
end violation_name

----------------------------------------------●
--メール送信
to send_mail(send_to, send_from, my_subject, my_body, my_attachmentFile)
	tell application "Mail"
		--activate
		set my_Message to make new outgoing message with properties {subject:my_subject, content:my_body & return & return, visible:false}
		tell my_Message
			set sender to send_from
			try
				make new to recipient at end of to recipients with properties {address:send_to}
				if class of my_attachmentFile is list then --複数の添付ファイル
					repeat with aFile in my_attachmentFile
						make new attachment with properties {file name:aFile} at after the last word of the last paragraph
						delay 3 --待ち時間を入れないとファイルが添付されない。
					end repeat
				else
					make new attachment with properties {file name:my_attachmentFile} at after the last word of the last paragraph
					
					delay 3
				end if
				send
			on error errmess
				display dialog my_subject & "の送信に失敗しました。" buttons {"キャンセル"} default button 1 with icon 1 --キャンセルで終了 
			end try
		end tell
	end tell
end send_mail

 AppleScriptでMail.appの添付書類を送る時、リストで渡せない。1ファイルづつrepeatしてattachmentを生成しないといけないっぽい。さらに添付してすぐにsendすると添付されてないまま送られちゃうのだ。ぐぬぬ...

*1:サービスによってはExif削除してくれるものもあるけど、そのまま垂れ流してるものあるよね... 大丈夫なの。あれ?

*2:ターミナルでImageMagickのmogrifyコマンド使うっていう方法もありますけど、まあ、コマンド打ちたくない... 省力化ですよ^^

*3:Web上からのアップロードってファイル数の制限があってやたら待たされるんですよね...