スポンサーサイト

Tags :
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

AppleScriptでJPEG画像がプログレッシブかどうかを判定する

AdobeのPhotoshopフォーラムに投稿されていたのを見て、ちょっと考えてみました。

ApplescriptでプログレッシブJPEGはわかりますか?
(Adobe Forums: フォーラム: Photoshop (Japan))

PhotoshopのAppleScriptリファレンスを眺めてみたり、保存した画像のXMPメタデータにそれらしい情報が含まれていないか見てみたんですが、Photoshopを使った解決法が見つからなかったので、Photoshopを使わない別の方法でやってみます。

通常この手の処理はバイナリデータを先頭から読んでいってマーカーの値が出てきたらそれを判別して……みたいな感じになりますが、AppleScriptでバイナリデータを扱うのはちょっと面倒そうなので、Unix系のOSで使える出来合いのライブラリに処理を投げてしまったほうが手取り早く、確実だと思います。

で、今回使用してみたのは『libjpeg』ライブラリに含まれる『rdjpgcom』コマンドで、シェルを使ってJPEG画像に関する情報を取り出す事ができます。このコマンドをAppleScriptの『do shell script』で呼び出してやります。

そのためにはMacに『libjpeg』をインストールしてやる必要がありますが、下のサイトでコンパイル済みのインストーラ形式のものが公開されています。

http://ethan.tira-thompson.org/Mac_OS_X_Ports.html
(@ITで紹介されていたものですが、インストーラの素性は保証できないので、利用は自身の判断で…今回必要なのは『rdjpgcom』コマンドだけなので、『libjpeg』本体は無くても良いようですが。)

上記インストーラでは『rdjpgcom』コマンドは『/usr/local/bin』にインストールされます。

このコマンドの使い方は、例えばデスクトップにある画像、ファイル名『baseline.jpg』の情報を見る場合、ターミナルで、
rdjpgcom -verbose /User/hogehoge/Desktop/baseline.jpg
のように -verbose オプションを付けてファイルのパスを渡してやれば、
JPEG image is 1280w * 1024h, 3 color components, 8 bits per sample
JPEG process: Baseline
のような形で返ってきます。

『rdjpgcom』コマンドは、JPEG画像以外のファイルを処理した場合、標準エラー出力に『Not a JPEG file』の文字列を返してくるので、メッセージを『try~on error』で拾えます。

AppleScriptから使う場合はこんな感じでしょうか。
on open drop
	repeat with aFile in drop
		tell application "Finder"
			set fPath to POSIX path of aFile as string
			set scpt to "/usr/local/bin/rdjpgcom -verbose " & quoted form of fPath
			try
				set rslt to do shell script scpt as string
				if rslt is not "" then
					display dialog name of aFile & return & word 3 of paragraph 2 of rslt
				else
					display dialog "不明"
				end if
			on error errStr
				display dialog errStr
			end try
		end tell
	end repeat
end open
上記のスクリプトではAppleScirpt側で、シェルから返ってきた文字列が入る変数rsltから『Progressive』『Baseline』を取り出していますが、
rdjpgcom -verbose /User/hogehoge/Desktop/baseline.jpg | grep process | awk '{ print $3 }'
のようにgrepとawkを通してやれば、シェル側で
Baseline
の文字列だけを取り出せます。(この場合、JPEG以外のファイルを処理すると何も返ってきません。)

結局AppleScriptでは出来てないじゃん!とか言われそうですが、Finderなどの処理を自動化しつつ、手に負えない処理はシェルや他の言語に丸投げするのがグルー(糊)な言語としてのAppleScriptの正しい使い方だと思っているので。
スポンサーサイト

オープンソースの画像補完ソフトウェア『GREYCstoration』

ちょっと前にスラドで紹介されてたオープンソースの画像補完ソフト、『GREYCstoration』が気になってたので使ってみました。
これは画像のノイズ除去や、マスクを使って画像の欠損部分を補完したり、なめらかに画像のリサイズが出来るもので、コマンドラインから使用します。

今回使ったのはMacOS X用(PPC版)なんですが、GREYCstorationの動作にはImageMagickが必要なので、Finkを使ってインストールしました(バージョンが若干古いです)。また、あらかじめX Window Systemを起動しておく必要があります。
(X Windowで起動してるxtermではなく、Terminal.appから使う場合は環境変数$DISPLAYが設定されてないと使えないかも知れません。)
実行ファイルはパスの通ったところにgreycstorationっていう名前でコピーしておきました。

JPEGノイズで荒れた画像に適用した例。



こちらは二度掛け。



マスクを使って文字を消す。
こんなマスクありかよって言うのは置いておいて。しっかりしたマスクさえ用意出来れば綺麗に補完してくれます。
greycstoration -inpaint hoge.jpg -m mask.jpg




処理が終わったあと、『S』キーで画像がカレントディレクトリにBMP形式で保存され、『I』キーで同じ処理を繰り返せます。
あと、処理した画像をPhotoshop等カラーマネジメントの効いたアプリで見ると色が変わって見える事がありますが、これはカラープロファイルの情報が失われたためで、その場合元の画像と同じプロファイルを指定してやれば元の色に戻ります。

ヘルプを見ると色々細かいパラメータがあるんですが、-inpaint オプションで補完するのにG4 Macだとやたら時間がかかったのであんまり試してません。

使い所があるような無いような感じですが、引き出しに入れておけば何かの時に役に立つかも知れないんじゃないかと。

画像に適切な拡張子を付けるAppleScript

◆画像ファイル専用◆

sipsを使ったAppleScriptその2。といっても、画像をいじったりはしないんですが。

仕事では大量に画像のファイル名を操作する事が割と多くて、この手のスクリプトは欠かせません。
で、sipsを使えば画像ファイルのフォーマットを判別出来るので、勝手に拡張子を付けてくれるスクリプトを書いてみました。
ただ、sipsはEPSファイルを扱う事が出来ないので、EPSを判別する部分だけ別に付け加えてます。

OS Xでは(■追記 これはOS XではなくPhotoshopCS2の仕様みたいです。CS3では改善されました)、ファイルを開く際にファイルタイプよりも拡張子が優先されて、 例えば実際のフォーマットは『EPS』なのに拡張子が『.jpg』だとエラーで開く事が出来ません。これは適切にファイルタイプが『EPSF』となっていても同様です。
なのでPhotoshopでJPEG画像を開いた時、『.jpg』の拡張子が付いた同名のEPSで上書き保存してしまうとダブルクリックで開かなくなってしまいます。
(Photoshopの『開く』メニューからでないと開けない)
あと、古くからMac使ってる人って拡張子を付けない習性があるように感じるんですが、そんな人たちから受け取った拡張子の付いて無い画像にも使えると思います。

ドロップレットとして保存したスクリプトに画像ファイルをドロップすると、元から拡張子が付いていれば適切な拡張子に変更、付いて無い場合は新たに拡張子を追加します。

一応、イジワルなファイル名でエラー処理のテストをしてますが、ファイル名の末尾にドットが並んでたりとか、変なファイル名には対応しきれないかも知れません。

Mac OS X 10.3.9で動作確認
property cr : (ASCII character 13)

on open drop
   set errList to {}
   tell application "Finder"
      activate
      repeat with theFile in drop
         set fName to name of theFile
         
         set newExt to my get_Extension(theFile) ----ファイルのフォーマットをチェックし、拡張子を得る
         
         if newExt is not "false" then
            ---- "." 以降4文字以内の末尾を拡張子として取得
            if fName contains "." and length of fName > 4 then
               set targetTxt to text -1 thru -4 of fName
            else
               set targetTxt to ""
            end if
            set currentExt to (do shell script "echo " & quoted form of targetTxt & " | sed 's/.*\.//'")
            if (count of character of currentExt) > 4 then
               set currentExt to ""
            end if
            ----既に拡張子が付いていた場合は現状の拡張子と置換
            if currentExt is not "" then
               do shell script "echo " & quoted form of fName & " | sed 's/" & quoted form of currentExt & "$/" & quoted form of newExt & "/'"
               set fName to result
            else
               ----拡張子が付いていなければ新たに付ける
               set fName to name of theFile & "." & newExt
            end if
            try
               set name of theFile to fName
            on error
               ----ファイル名変更時Finderでエラーが起きた場合エラーリストに追加
               set errList to errList & name of theFile
            end try
         end if
      end repeat
      
      if errList is not {} then
         beep
         set myResult to ""
         repeat with aElement in errList
            set myResult to myResult & aElement & cr
         end repeat
         display dialog "以下のファイルは拡張子を付けられませんでした。(ファイル名のダブり等)" & cr & cr & myResult
      end if
   end tell
end open


on get_Extension(theFile)
   set fPath to POSIX path of theFile as Unicode text
   try
      set newExt to 2nd word of (do shell script "sips -g all " & quoted form of fPath & " | grep format")
      if newExt is "tiff" then set newExt to "tif"
      if newExt is "jpeg" then set newExt to "jpg"
   on error
      ----sipsでフォーマットが判明しない場合、EPSかどうかをチェック
      open for access theFile without write permission
      set readText to read theFile to 20
      close access theFile
      if readText contains "EPSF" or readText contains "ナミモニ" then
         set newExt to "eps"
      else
         set newExt to "false"
      end if
   end try
   return newExt
end get_Extension

カラープロファイル毎に画像ファイルを分別するスクリプト

AppleScriptのImage Events(とかsipsコマンド)で何か出来ないかと色々考えてたんですが、画像をいじるのはPhotoshopのアクションで事足りてるし、そうなると後は画像の情報を得て何か処理をするくらいかなーーとか考えつつ色々と試してます。

で、手始めに画像ファイルに含まれてるカラープロファイル毎に、ファイルを分別するスクリプトを作ってみました。

ドロップレットとして保存したスクリプトに画像ファイルをドラッグすれば、同じプロファイルを持つ画像が一つのフォルダにまとまります。

素性の分からないJPEG画象とかをまとめて受け取った時なんかに使えるかも知れませんが、自分でも利用価値があるのかどうかよく分かりません。

プロファイル名を得るのはImage Eventsよりsipsコマンドの方がシンプルに出来そうだったので、do shell scriptでsips使う様にしました。
sipsで処理出来ないファイル(EPSや画像でないファイル)や、プロファイル名を得られないフォーマット(PSD等)、プロファイルが埋め込まれてない画像は何も処理をしないようになってます。

Mac OS X 10.3.9で動作確認

on open drop
   repeat with theFile in drop
      set myResults to my get_ImageProps(theFile)
      
      --プロファイル名を得られないファイルは処理対象としない(falseにする)
      set color_space to 1st item of myResults
      
      set file_format to 2nd item of myResults
      set profile_name to 3rd item of myResults
      
      if color_space is not "false" then
         tell application "Finder"
            set fName to name of theFile as string
            set newFolderName to profile_name & "@" & color_space & "-" & file_format
            set currentDir to parent of theFile as Unicode text
            if not (folder newFolderName of folder currentDir exists) then
               make new folder with properties {name:newFolderName} at currentDir
            end if
            move theFile to folder newFolderName of folder currentDir
         end tell
      end if
   end repeat
end open


on get_ImageProps(theFile)
   set profile_name to ""
   set file_format to ""
   try
      set fPath to POSIX path of theFile as Unicode text
      set color_space to 2nd word of (do shell script "sips -g all " & quoted form of fPath & " | grep space")
      set file_format to 2nd word of (do shell script "sips -g all " & quoted form of fPath & " | grep format")
      set profile_name to (do shell script "sips -g all " & quoted form of fPath & " | grep profile | sed 's/profile: //'")
      
      ---なぜか頭に何らかのスペース(?)が入るので除去
      set profile_name to (items 3 thru -1) of profile_name as Unicode text 

      if profile_name is "" then set color_space to "false"
   on error
      set color_space to "false"
   end try
   return {color_space, file_format, profile_name}
end get_ImageProps

画像フォーマットとファイルサイズ

Tags : [Image]
仕事で扱う画像ファイルを整理していて、同じ画像サイズ(ピクセル数)でもPhotoshopのPSDとTIFFでそれぞれ保存した時の容量が違う(TIFFの方が大きい)のが気になったのでメモ。

フォーマットごとのファイルサイズの違いは、普段の作業で漠然と認識してはいたけれど、具体的に比較していた訳では無かったし、ちょっと数字で再確認・・・・

以下は絵柄やサイズの違う30点程の高解像度画像(CMYK、RGB混在)の平均値で比較。
スタジオでの商品撮影なんかだと、背景がフラットな場合が多いので、更に圧縮率が高まりそう。

『TIFF(圧縮なし)』を100とした場合
『PSD』 85
『EPS(バイナリ)』 130
『EPS(JPEG最高画質)』 13
『TIFF(LZW圧縮)』 38

まず、TIFF(圧縮なし)の場合、絵柄に関係なく同じ画像サイズ(ピクセル数)の画像は全て容量が同じ。

それに対して、PSDはピクセル数が同じでも、絵柄によるファイルサイズの違いが有り、フラットな絵柄になるとかなりファイルサイズが小さくなるので、何らかの圧縮が行われてる。
調べてみると、Photoshop3.0以降では、PSDはBMPと同じくRLE(ランレングス法)で圧縮されてるらしい。(試しにPhotoshop2.0互換で保存すると、TIFFとほぼ同じ、正味のピクセル数でファイルサイズが決まる)

これが、『EPS-バイナリ』(JPEGエンコーディング無し)だと、PSDの1.5倍近い容量になるので、プレビュー画像が含まれてるとはいえ、かなり冗長な感じ。
『EPS-JPEG最高画質』になると、当然、一気に容量が小さくなる。通常の仕事であれば、品質的に特に問題も無く、そのまま出力に使えるこの形式で保存。
但し、何度も直し(色補正)が入る様な仕事の場合は『EPS-バイナリ』で保存してるので、これをPSDに置き換えるとかなり節約できる。

TIFFのLZW圧縮を使って保存した場合は、圧縮無しのTIFF画像の約1/2の容量になるので、デジカメ撮影で入稿された画像(TIFFでの入稿が多い)を劣化させずに保存したい場合はこれを使うのが良いかも。(まぁ、ほとんどの場合、JPEG保存でも問題ないのだけれど・・・)
FTPやHTTP経由でTIFF画像を受け取りたい場合も有効かな。その方がカメラマン自身も時間取られなくて済むし。でも、普通はJPEG使うか・・・

しかし、圧縮を行うフォーマットだと、確実に演算処理が増えている筈なのに、保存の時の体感速度の差は感じられない。実際は時間がかかってるのかもしれないけれど、最近のマシンパワーなら問題にならないレベルなのかも・・・(むしろファイルサイズの大きさによる保存やコピー等、ディスクアクセスによる違いの方が大きい)
Profile
choco
Author : choco

印刷・製版の現場を経て、広告制作会社でPhotoshopを使ったビジュアル制作を担当。

→現在は車載機器開発ベンダにて、組み込み3Dデータ作成やUIデザインなどを行っています。

Categories
Favorites


Search
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。