2009年2月アーカイブ

検索してこのページへたどり着いたあなたへ。

Perlの世界へようこそ。
use strict ワールドへようこそ。

Perl/CGI初心者へ。 use strictは絶対に書きましょう!!

書き方
#!/usr/bin/perl
use strict;
または
#!/usr/local/bin/perl
use strict;
解説はこちら: Perl/CGIに必ず登場するuse strictの解説(初心者向け)

Perl/CGI初心者へのアドバイス。

よい子のお約束です。
  • use strictと書かずに、Perlプログラムを書いてはいけません。
  • use strictと冒頭に書かれていないPerlのソースコードをマネしてはいけません。
  • use strictと書かれていないPerl/CGIの参考書は参考にしてはいけません。

use strcitを知らないと損をします。

use strict無しのPerl、
それは古文です。
いや、古Perlです。

もしあなたがuse strict無しの「古Perl」を身に着けてしまうと、後で必ずuse strict有りの「今Perl」を勉強しなおすハメになります。
これはものすごい時間の無駄です。

だから、Perlを勉強し始めたら、絶対書きましょう。
幸せの呪文です。

さあ、ご一緒に
use strict !!
use strict !!
use strict !!

いや、正しくはこう。
#!/usr/bin/perl
use strict;
または
#!/usr/local/bin/perl
use strict;
out1.jpgのサムネール画像

montageコマンドを使うと、日本語のテキストを画像に入れることができます。
私は下記の通りにやったらできました。

日本語テキストファイルをUTF8でカレントディレクトリに保存しておく

下記のようなテキストファイルを作って、UTF8でc:¥に保存します。

label.txt
日本語にほんご あいうえお

日本語のフォントファイルをカレントディレクトリに保存する

さざなみフォントというのをダウンロードして、 sazanami-gothic.ttf をカレントディレクトリに置いてみました。

montageコマンドを実行

C:¥> montage -geometry +0+0 -background White -label @label.txt 
     -pointsize 250 -font sazanami-gothic.ttf in.jpg  out.jpg
(見やすくするために改行してますが、実際は改行なしです)

おまけ


文字化けしがちな機種依存文字も試してみたらうまくいきました。


out2.jpg
JPEGのExif情報のIFD0タグの"0x0112"、すなわちOrientation属性の定義について調べました。

Orientationの定義


Orientationどう補正すれば正しい向きになるか
1そのまま
2上下反転(上下鏡像?)
3180度回転
4左右反転
5上下反転、時計周りに270度回転
6時計周りに90度回転
7上下反転、時計周りに90度回転
8時計周りに270度回転


経緯

仕様はここに書いてありますが、私は何回読んでも理解できませんでした。

もっと分かりやすい説明はないかとネット上を探し回ったら、ありました。
CPANのImage::ExifToolのソースコードの中に分かりやすい対照表が。
http://cpansearch.perl.org/src/EXIFTOOL/Image-ExifTool-7.60/lib/Image/ExifTool/Exif.pm
Perlコミュニティの底力を垣間見ました。
脱帽です。

%orientation = (
    1 => 'Horizontal (normal)',
    2 => 'Mirror horizontal',
    3 => 'Rotate 180',
    4 => 'Mirror vertical',
    5 => 'Mirror horizontal and rotate 270 CW',
    6 => 'Rotate 90 CW',
    7 => 'Mirror horizontal and rotate 90 CW',
    8 => 'Rotate 270 CW',
);
どのような処理をすれば正しい向きに補正できるのかが書かれています。

これを日本語に訳したのが、上の表です。

あ~長年のモヤモヤがすっきりした!!
画像の回転方向(ExifのOrientaionタグの値)を取得する方法
// identify-js.js

var im = new ActiveXObject("ImageMagickObject.MagickImage.1");

var file1 = WSH.Arguments(0);

var msg = im.Identify( "-format", "%[Exif:Orientation]¥n",  file1 );

WSH.Echo(msg);
下記のように実行する。
C:¥>cscript c:¥identify-js.js a.jpg
8
ここ、、これだ。。
これがやりたかったの!!
超感激。

複数画像を一気に調べることも可能。
// identify2-js.js

var im = new ActiveXObject("ImageMagickObject.MagickImage.1");

var file1 = WSH.Arguments(0);
var file2 = WSH.Arguments(1);
var file3 = WSH.Arguments(2);

var msg = im.Identify( "-format", "%[Exif:Orientation]¥n",  file1, file2,file3 );

WSH.Echo(msg);
C:¥>cscript C:¥identify2-js.js a.jpg b.jpg c.jpg
8
8
1
こういうのはループ回した方がいいかもしれない。

これでだいぶ材料は揃った。

参考:
http://imagemagick.org/script/ImageMagickObject.php
画像の幅と高さのピクセル数を取得する方法
// identify-js.js

var im = new ActiveXObject("ImageMagickObject.MagickImage.1");
var file_in = WSH.Arguments(0);

var msg = im.Identify( "-format", "%w,%h",  file_in );
WSH.Echo(msg);
上記スクリプトをc:¥identify-js.jsとして保存する。
下記のように実行する。
C:¥>cscript identify-js.js a.jpg
3504 2336
をを~。
すごい!!
便利すぎる。

複数画像を一気に調べることも可能。
// identify2-js.js

var im = new ActiveXObject("ImageMagickObject.MagickImage.1");
var file1 = WSH.Arguments(0);
var file2 = WSH.Arguments(1);

var msg = im.Identify( "-format", "%w,%h¥n",  file1, file2 );
WSH.Echo(msg);
C:¥>cscript identify2-js.js a.jpg b.jpg
3504 2336
3504 2336
まあfsoのfilesコレクションをループで回してもいいんだけど。

JscriptからImageMagickを扱う方法がだいぶわかってきた。
Windows環境であれば、PerlMagickなんか使う必要ないかも。

参考:
http://imagemagick.org/script/ImageMagickObject.php
Identifyコマンドで、画像の幅と高さのピクセル数を取得できます。

C:¥>identify -format "%w %h" a.jpg
3504 2336
複数画像を一気に調べることも可能。
C:¥>identify -format "%w %h¥n" a.jpg  b.jpg
3504 2336
3504 2336

さて、次はJScript/WSHでこれをやってみるのだ!

参考:
http://www.imagemagick.org/Usage/basics/#identify
JPEG画像のExif情報から、例えば画像の方向(Orientation)だけを取得したいときはこうすればよい。
C:¥>identify -format "%[Exif:orientation]" a.jpg
8
結果が"8"の場合は、立っている人が↓このような感じになっている状態。
\  \
 ---○
/   \
時計回りに270℃回転してあげればよい。

複数の画像を一度に調べることもできる。
C:¥>identify -format "%[Exif:orientation]¥n" a.jpg b.jpg
8
1
参考
http://www.imagemagick.org/script/escape.php
ImageMagickでExif情報を取得するには、identifyコマンドを使う。
c:¥>identify -verbose a.jpg

Image: small.jpg
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Class: DirectClass
  Geometry: 43x64+0+0
  Resolution: 350x350
  Print size: 0.122857x0.182857
  Units: PixelsPerInch
  Type: TrueColor
  Endianess: Undefined
  Colorspace: RGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit
  Channel statistics:
    red:
      min: 0 (0)
      max: 255 (1)
      mean: 130.382 (0.511303)
      standard deviation: 58.7927 (0.230559)
      kurtosis: -0.00290861 (-1.14063e-005)
      skewness: 0.00016144 (6.33097e-007)
    green:
      min: 1 (0.00392157)
      max: 255 (1)
      mean: 115.273 (0.452049)
      standard deviation: 62.7084 (0.245915)
      kurtosis: -0.00327006 (-1.28238e-005)
      skewness: 0.00145026 (5.68729e-006)
    blue:
      min: 0 (0)
      max: 255 (1)
      mean: 99.0189 (0.388309)
      standard deviation: 59.772 (0.2344)
      kurtosis: -0.00164533 (-6.45228e-006)
      skewness: 0.00271198 (1.06352e-005)
  Rendering intent: Undefined
  Interlace: None
  Background color: white
  Border color: rgb(223,223,223)
  Matte color: grey74
  Transparent color: black
  Page geometry: 43x64+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: JPEG
  Quality: 92
  Orientation: TopLeft
  Properties:
    aux:Firmware: 1.0.5
    aux:FlashCompensation: 0/1
    aux:ImageNumber: 0
    aux:Lens: EF-S17-85mm f/4-5.6 IS USM
    aux:LensInfo: 17/1 85/1 0/0 0/0
    aux:SerialNumber: 510208736
    create-date: 2009-02-03T21:16:50+00:00
    crs:AlreadyApplied: True
    crs:BlueHue: 0
    crs:BlueSaturation: 0
    crs:Brightness: 0
    crs:CameraProfile: Embedded
    crs:CameraProfileDigest: 1AC384680095B8A42267EF85E12B8E82
    crs:ChromaticAberrationB: 0
    crs:ChromaticAberrationR: 0
    crs:Clarity: 0
    crs:ColorNoiseReduction: 0
    crs:Contrast: 0
    crs:ConvertToGrayscale: False
    crs:Defringe: 0
    crs:Exposure: +0.66
    crs:FillLight: 0
    crs:GreenHue: 0
    crs:GreenSaturation: 0
    crs:HasCrop: False
    crs:HasSettings: True
    crs:HighlightRecovery: 0
    crs:HueAdjustmentAqua: 0
    crs:HueAdjustmentBlue: 0
    crs:HueAdjustmentGreen: 0
    crs:HueAdjustmentMagenta: 0
    crs:HueAdjustmentOrange: 0
    crs:HueAdjustmentPurple: 0
    crs:HueAdjustmentRed: 0
    crs:HueAdjustmentYellow: 0
    crs:IncrementalTemperature: 0
    crs:IncrementalTint: 0
    crs:LuminanceAdjustmentAqua: 0
    crs:LuminanceAdjustmentBlue: 0
    crs:LuminanceAdjustmentGreen: 0
    crs:LuminanceAdjustmentMagenta: 0
    crs:LuminanceAdjustmentOrange: 0
    crs:LuminanceAdjustmentPurple: 0
    crs:LuminanceAdjustmentRed: 0
    crs:LuminanceAdjustmentYellow: 0
    crs:LuminanceSmoothing: 0
    crs:ParametricDarks: 0
    crs:ParametricHighlights: 0
    crs:ParametricHighlightSplit: 75
    crs:ParametricLights: 0
    crs:ParametricMidtoneSplit: 50
    crs:ParametricShadows: 0
    crs:ParametricShadowSplit: 25
    crs:RedHue: 0
    crs:RedSaturation: 0
    crs:Saturation: 0
    crs:SaturationAdjustmentAqua: 0
    crs:SaturationAdjustmentBlue: 0
    crs:SaturationAdjustmentGreen: 0
    crs:SaturationAdjustmentMagenta: 0
    crs:SaturationAdjustmentOrange: 0
    crs:SaturationAdjustmentPurple: 0
    crs:SaturationAdjustmentRed: 0
    crs:SaturationAdjustmentYellow: 0
    crs:Shadows: 0
    crs:ShadowTint: 0
    crs:SharpenDetail: 25
    crs:SharpenEdgeMasking: 0
    crs:SharpenRadius: +1.0
    crs:Sharpness: 0
    crs:SplitToningBalance: 0
    crs:SplitToningHighlightHue: 0
    crs:SplitToningHighlightSaturation: 0
    crs:SplitToningShadowHue: 0
    crs:SplitToningShadowSaturation: 0
    crs:ToneCurveName: Linear
    crs:Version: 1.0
    crs:Vibrance: 0
    crs:VignetteAmount: 0
    crs:WhiteBalance: As Shot
    dc:format: image/jpeg
    exif:ApertureValue: 6/1
    exif:Artist: KAKINO MINORU
    exif:ColorSpace: 1
    exif:Compression: 6
    exif:CustomRendered: 0
    exif:DateTime: 2008:03:25 10:15:16
    exif:DateTimeDigitized: 2008-03-17T13:24:15.00+09:00
    exif:DateTimeOriginal: 2008-03-17T13:24:15.00+09:00
    exif:ExifImageLength: 3888
    exif:ExifImageWidth: 2592
    exif:ExifOffset: 232
    exif:ExifVersion: 0221
    exif:ExposureBiasValue: 0/1
    exif:ExposureMode: 1
    exif:ExposureProgram: 1
    exif:ExposureTime: 1/60
    exif:Fired: True
    exif:Flash: 9
    exif:FNumber: 8/1
    exif:FocalLength: 24/1
    exif:FocalPlaneResolutionUnit: 2
    exif:FocalPlaneXResolution: 3888000/876
    exif:FocalPlaneYResolution: 2592000/583
    exif:Function: False
    exif:ISOSpeedRatings: 400
    exif:JPEGInterchangeFormat: 758
    exif:JPEGInterchangeFormatLength: 6262
    exif:Make: Canon
    exif:MaxApertureValue: 4/1
    exif:MeteringMode: 5
    exif:Mode: 1
    exif:Model: Canon EOS 40D
    exif:NativeDigest: 36864,40960,40961,37121,37122,40962,40963,37510,40964,36867,36868,33434,33437,34850,34852,34855,34856,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37396,41483,41484,41486,41487,41488,41492,41493,41495,41728,41729,41730,41985,41986,41987,41988,41989,41990,41991,41992,41993,41994,41995,41996,42016,0,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,23,24,25,26,27,28,30;42A8D7E4F934B0276C2BDB6FF7CAE3BC
    exif:Orientation: 1
    exif:PixelXDimension: 2592
    exif:PixelYDimension: 3888
    exif:RedEyeMode: False
    exif:ResolutionUnit: 2
    exif:Return: 0
    exif:SceneCaptureType: 0
    exif:ShutterSpeedValue: 5906891/1000000
    exif:Software: Adobe Photoshop CS2 Windows
    exif:SubSecTimeDigitized: 00
    exif:SubSecTimeOriginal: 00
    exif:WhiteBalance: 0
    exif:XResolution: 350/1
    exif:YResolution: 350/1
    jpeg:colorspace: 2
    jpeg:sampling-factor: 1x1,1x1,1x1
    modify-date: 2009-02-03T21:16:50+00:00
    photoshop:ColorMode: 3
    photoshop:History: 
    photoshop:ICCProfile: sRGB IEC61966-2.1
    photoshop:LegacyIPTCDigest: D816136FDBC7BF30093CE92B47E5F232
    signature: 4996f4b138140b398e5ae1ad9d80061acd58dc99c1eddd941ed7800177675dee
    tiff:ImageLength: 3888
    tiff:ImageWidth: 2592
    tiff:Make: Canon
    tiff:Model: Canon EOS 40D
    tiff:NativeDigest: 256,257,258,259,262,274,277,284,530,531,282,283,296,301,318,319,529,532,306,270,271,272,305,315,33432;E8748A7302E4E9DF5AF6F026FDB8BED5
    tiff:Orientation: 1
    xap:CreateDate: 2008-03-17T13:24:15+09:00
    xap:CreatorTool: Adobe Photoshop CS2 Windows
    xap:Label: レッド
    xap:MetadataDate: 2008-03-25T10:15:16+09:00
    xap:ModifyDate: 2008-03-25T10:15:16+09:00
    xap:Rating: 1
    xapMM:DocumentID: uuid:BC8958FA07FADC11BD4FB48E4BEA2DBF
    xapMM:InstanceID: uuid:855DE2DB08FADC11BD4FB48E4BEA2DBF
  Profiles:
    Profile-8bim: 7810 bytes
    Profile-exif: 7026 bytes
    Profile-icc: 3144 bytes
      IEC 61966-2.1 Default RGB colour space - sRGB
    Profile-iptc: 25 bytes
      unknown[2,0]: 
    Profile-xmp: 21901 bytes
  Artifacts:
    verbose: true
  Tainted: False
  Filesize: 41.3kb
  Number pixels: 2.69kb
  Version: ImageMagick 6.4.8-5 2009-01-10 Q16 OpenMP http://www.imagemagick.org
僕が欲しいのはこの中の「exif:Orientation: 1」の箇所だけなんだけど、どうしたらよいものやら。
しかもコマンドではなくてJScriptからこれを取得したい。
前回のとほぼ同じですが、 縮小する際にExif情報をカットしくれます。
var im = new ActiveXObject("ImageMagickObject.MagickImage.1");
var file_in = WSH.Arguments(0);
var file_out = WSH.Arguments(1);

var msg = im.Convert( "-thumbnail", "64x64", file_in, file_out );
WSH.Echo(msg);
使い方
上記スクリプトをthumbnail.jsなどと保存して、
コマンドプロンプトから
c:¥> cscript thumbnail.js big.jpg small.jpg
手元のJPEGファイルで試したところ、コンバート後のファイルサイズは

Exif情報を残した合 - 42KB
Exif情報を削除した場合 - 3KB

差は歴然ですね。
42KB中、実に38KBはExif情報で占められていることになります。
アクセス数の多いWebサイトでは、Exifを削除するだけで劇的にWebサーバのパフォーマンスがあがりますね。

参考:
http://www.imagemagick.org/Usage/resize/#thumbnail
http://www.imagemagick.org/script/command-line-options.php#thumbnail
例えば、コマンドプロンプトで下記のような位置にいるとき、
C:¥rogram Files¥ImageMagick-6.4.8-Q16¥ImageMagickObject>
このフォルダをエクスプローラで開きたいことがたまにあるわけです。

こういう場合、今までは

コマンドプロンプト上の絶対パスをコピー

エクスプローラをWindowsキー+Eで新規立ち上げ

アドレスバーに絶対パスを貼り付け

などとやっていました。

しかし、これを一瞬でやる方法があることに気が付きました。
C:¥rogram Files¥ImageMagick-6.4.8-Q16¥ImageMagickObject> Explorer .
超便利!!感動した!!

しかもしかも、".."と書くと親フォルダも開けちゃいます。
C:¥rogram Files¥ImageMagick-6.4.8-Q16¥ImageMagickObject> Explorer ..
"..¥.."で親フォルダの親フォルダが開く。
C:¥rogram Files¥ImageMagick-6.4.8-Q16¥ImageMagickObject> Explorer ..¥..
すげーすげー。 もちろん子供フォルダも簡単に開ける。
C:¥rogram Files¥ImageMagick-6.4.8-Q16¥ImageMagickObject> Explorer Tests
やってみたらめっちゃ簡単だった。
var im = new ActiveXObject("ImageMagickObject.MagickImage.1");
var file_in = WSH.Arguments(0);
var file_out = WSH.Arguments(1);

var msg = im.Convert( "-geometry", "64x64", file_in, file_out ); 

上記コードをc:¥conv.jsで保存して、コマンドラインから呼び出す。
c:¥>cscript conv.js big.jpg small.jpg
このケースでは、元画像の縦横比は保持されます。 Exif情報も保持されます。
C:¥> D:
D:¥>
カレントディレクトリをC:¥からD:¥へ移動したいときは、上記のようにやる。
cdコマンドではボリューム(ドライブ)を超えての移動はできない。
めちゃ簡単です。
Altキー+「漢字」キーを押すと日本語入力ができます。 WS000000.JPG

test

test

test

test

「ディレクトリではありません」と出て削除できないのは、末尾の"/"が原因。
$ rm foo/    → ディレクトリではありません。
$ rm foo     → 削除できる

人気記事

このアーカイブについて

このページには、2009年2月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2009年1月です。

次のアーカイブは2009年5月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

最近の人気記事