逆襲のOS/2(2004.12.24/2014.05.28upd)

グラフィックス・メモ


●アスペクト比 (2014.05.26)

画像のアスペクト比を計算すること自体は簡単だが、 使用頻度の高い4:3と16:9、正方形、及びそれ以上の縦長/横長画像が簡単に区別できると便利。そこで、アスペクト比を4倍して、小数部分を切捨てたところ、次のような値が得られた。

アスペクト比TRUNC(width/height*4)
16:9横 7
-- 6
4:3横 5
1:1(正方形)4
4:3縦 3
16:9縦 2

こうした値を画像のプロパティとして持たせておけば、 整数一桁でおおよそのアスペクト比分類ができる。 2よりも小さければ縦に非常に長く、7よりも大きければ横に非常に長い。 ただし、縦にいくら長くてもこの値は0より小さくはならないが、 横に長い画像には上限がある。 縦横比が2.5倍を越えると整数一桁に収まらないし、 16進数を使うにしても4倍未満が一桁の限界になる。 もちろん一桁に拘らなければ何の問題もないし、 IF文一つでどうにでもなるが、それもスマートではない。

▼縦横判別

縦横比の値ではなく、単純に縦長か横長か、或は正方形かを識別したければ、

SIGN(width-height)
が一番簡単。ただし、これだと-1/0/1という値を取るため、ちょっと扱いにくい。 そこで、1を足して、0/1/2としてやると扱いやすい。 ここでは、この値を仮に「PSL値」(Portrait/Square/Landscape)と呼ぶ。 「正方形を含む縦長画像」や「正方形を含む横長画像」のような条件も、 このPSL値の差で判別すると便利。
PSL1=SIGN(width1-height1)+1
PSL2=SIGN(width2-height2)+1
IF ABS(PSL1-PSL2)<=1 THEN ....
てな感じになる。 単純に二つの画像の縦長・横長・正方の組み合わせを考えると9パターンあるが、 この方法ならば論理式1つで識別できる。

▼縦横サイズの取得

ところで、アスペクト比の元になる縦横サイズだが、 これはGBMRXを使うと簡単に取得できる。

call RxFuncAdd 'GBM_LoadFuncs', 'GBMRX', 'GBM_LoadFuncs'
call GBM_LoadFuncs

rc=GBM_FileHeader(img,'','header.')
asp=SIGN(header.width-header.height)+1
てな感じになる。 もちろん、ImageMagickのidentifyなどを使っても取得できるが、 上記のようにライブラリ関数で直接取得する方がスマート。


●複数画像の印刷 (2009.12.08)

PMViewを使えば、複数画像の一括印刷指定は可能(FileOpenダイアログで指定)。ただし、それぞれ単体のジョブになるので、複数のページを1枚の用紙に割り付けて、袋とじのようにするのは不可能。

複数画像の印刷を単一ジョブにするには、画像自体を一本にバインドしないといけない。ただし、主要フォーマットで複数ページが持てるのはTIFFだけ。(GIFも持てないことはないか…アニメ用なんで、サイズが異なるとちと問題)

で、マルチページTIFFを作成するには、ImgaeMagickで;

	convert -adjoin page01.tif page02.tif total.tif
みたいなカンジにする。ワイルドカードが使えるから、page??.tifみたいな表記も可能なようだ。ただ、TIFF画像はハンパじゃない大きさになるのがチト問題。なので、画像をHTMLに貼り付けて印刷するという方法の方が便利……カナ? HTMLの印刷時の強制改ページに関して「PCうそつき講座」の「HTMLメモ」参照。

●REXXによるBMPデータの読み出し (2008.02.10)

画像全体の明るさの平均値が知りたい。なんでそんな変な情報を欲しがるのかと言うと、壁紙に使用する画像の明るさに応じて、アイコンの文字色を自動的に変更したいから。背景が黒い画像ならば明るい文字に、逆に背景が白っぽい画像ならば暗い文字にしないと視認性が悪い。でも、そんな変な情報を取得できるツールなんてなさそうだ。ないなら自作しかない…ということで、REXXでBMPデータの中身を直接読むことにした。まだ完成にはほど遠いが、一応、BMPデータの読み出し自体は成功した。画像の左端1/5くらいの領域のビットマップデータを足し込む(あるいは、明るさの閾値を決めてそれ以下のビット数をカウントする)とよいだろう。

【追記】この用途に限定するなら、GBMを使ってテキスト形式のPGMやPPMに変換する方が便利だろう。GBMSIZEで1×5ドットのPGM(テキスト)に変換すれば、最初のドットの値がそのまま画面左端の明るさと相当する。(2014.05.24)

●OS/2のブートロゴ

PMViewを使えば、通常画像(Jpeg等)をロゴ形式に変換可能。オプションで3.x用と4.x用が選べる。3.xと4.xの違いは縦のドットサイズだけのようだ(3.xは640×400ドット、4.xは640×480ドット)。作成したロゴ画像を「OS2LOGO」(拡張子なし)とリネームして、ブートドライブのルートにおけばよい。オリジナルの「OS2LOGO」は「OS2LOGO.ORG」とでもして保管しておくこと(不可視属性やシステム属性が設定されていた記憶があるので注意)。

ただし、Warp 4.xのロゴではファイルサイズに制限がある。大きすぎるとブート時にTRAPする。目安は140KB以下(経験値)。ファイルサイズが140KBを超えたら、縦を20ドット程度カットして460ドットにすると良いだろう。なお、ロゴは一応圧縮形式らしく、同じドット数でもファイルサイズはかなり異なる。たとえば、オリジナルのロゴは640×480でも60KBしかない。PMViewでセーブ時にオプションでエンコードを掛けると、さらにちょっとだけ小さくなる。が、これで小さくしてもあまり意味はなさそうだ。

●PMViewのライトテーブル的使い方

大量に溜まった画像データ(何のデータだ!?)を効率良く整理したい。具体的には、サムネール形式の画像ファイル一覧から、任意の一枚をビューアに表示して中身を確認し、適当なフォルダに分類保存したい。Windows XPの[マイピクチャ]フォルダは、ほぼこの作業を想定して設計されているものと思われる。これに相当する機能が欲しい。

で、OS/2でこの作業をする際に問題になるのは、ビューアの位置と大きさ。たいていのビューアはファイルを元サイズで表示するため、一枚ごとに大きさが変わる可能性があるし、画像が画面の大半を覆ってしまうため、中身を確認した後、ビューアウィンドウを閉じないとファイル操作ができない。

しかし、ビューアウィンドウをデスクトップ上に固定サイズ・固定位置で表示することができれば、この問題は解決する。そこで、PMViewのオプションを次のように設定する。(レはオン、□はオフ)。なお、Ver.1.05ではPMView再起動後にこの設定が有効になるようだ。

 レ[View|Zoom image to fit window]
 □[Window|When loading a new image]

左上がビューア画面、左下が分類用フォルダ、右半分がサムネール一覧(PMViewのFile|Open)。

●PMViewのサムネールアイコンの操作が重い (2007.04.14)

PMViewのOpenウィンドウでサムネールアイコンをドラッグする場合、操作が異様に重くなることがある。特に、OS/2を長時間使用するとこの現象が顕著になる。ということで、これは、どうやらPMViewの問題ではなく、OS/2のシステム自体に原因があるようだ。おそらく元凶はシステムキャッシュ。★その後、これはキャッシュではなくPMView自体の問題と判明。その証拠に、PMViewの操作が重くなっても、PM上のファイル操作は全く重くならない。また、同じ環境でもPMView Proならばスムーズに操作できる。したがって、以下の説明は完全に的外れ。キャッシュをどういじっても関係はないようだ(2008.04.05)★

サムネールアイコンをドラッグしようとすると、システムはそのファイルを即座にキャッシュに記憶するのだが、その際キャッシュの管理に非常に大きなCPUパワーが必要で、その処理に時間が掛かっているらしい。となれば、選択肢は二つ。キャッシュをうんと大きくして管理を楽にするか、逆にゼロにして管理不要にするか。しかし、結論から言えばどちらもダメ。HPFSのキャッシュはCONFIG.SYS中の、

IFS=D:\OS2\HPFS.IFS /CACHE:1024
の行で設定できるが、残念ながら64KB〜2048KBの範囲しか有効にならない。ゼロにもできないし、飛躍的に拡大もできない。そこで、対処療法だが、Openウィンドウですべてのアイコンを選択し、ウィンドウ内でごく僅かにドラッグして放置する。この操作ですべてのアイコンがキャッシュに記憶されるので、以後の操作が非常に軽くなる。ただし、この操作をするとCPU使用率が100%になり、数秒〜数分間すべての操作が不可能になる。WarpCenterのCPUメーターを見て処理の終了を確認すること。

【追記】おそらく、この問題の本質はキャッシュではなく、INIがらみの問題ではないかと思う。(2014.05.24)

●画像のリサイズとフォーマット変換、色調変換

画像のリサイズやフォーマット変換にはImageMagickが便利。EMXのツールだが、コマンドラインで使うだけなら、X-Windowは不要。ImageMagickは複数ツールのパッケージで、リサイズやフォーマット変換にはconvertを、元画像のサイズ取得にはidentifyを使う。このほか、画像の合成やγ値の補正、輪郭強調などさまざまな処理が行えるツールも含まれている。

◎サイズ変換・フォーマット変換
構文)convert -geometry <x-size>x<y-size> <input-file> <output-file>
用例)convert -geometry 300x400 myphoto1.jpg myphoto2.gif
なお、このサイズ変換では、アスペクト比を保持したまま、指定されたサイズの矩形に収まるようにリサイズされる。たとえば、600×400の画像を120x120にリサイズすると、実際には120×80となる。サムネイルの作成などにはこの方が便利。
⇒アスペクト比を変更したい場合は120x120!のように、末尾に「!」を付ける。
⇒テキスト形式のPMM/PGM/PGMに変換したい場合は「-compress none」を付ける。

◎JPEG変換のクオリティ指定
構文)convert -quality <value> <inp-file> <jpeg-file>
用例)convert -quality 90 pic.bmp pic.jpg
<value>にクオリティを指定する。jpegの場合は0(最低画質)〜100(最高画質)の範囲で指定する(他の不可逆圧縮形式の場合は指定する数値の範囲が異なる)。

◎画像の矩形切り出し(crop)
構文)convert -crop <width>x<height>{±<x0>±<y0>} <input-file> <output-file>
用例)convert -crop 200x200+100+100 myphoto1.jpg myphoto2.gif
矩形領域の指定の仕方は、x0とy0で始点を指定し、weidthとheightで幅と高さを指定する。上記の例では(100,100)-(300,300)の領域を切り出す。始点の指定は省略できるが、なぜかREXX内では始点指定をしないと、出力ファイル名の末尾に「.0」が付くことがある。

◎画像サイズ取得
構文)identify <file>
用例)identify myphoto.jpg > tempfile (出力をファイルにリダイレクト)
出力結果をREXXで変数stに読み込んで、PARSE VAR st fname xsize 'x' ysize dummyとすれば、xサイズとyサイズが取得できる。

◎輝度、彩度、色相の変更
構文)convert -modulate <brightness,saturation,hue> <input-file> <output-file>
用例)convert -modulate 0,-5,0 myphoto.jpg myphoto2.jpg (彩度をやや弱くする)
輝度、彩度、色相は3つセットで指定する。値は0を基準に+/-で指定する(-100〜+100?)。なお、資料によっては100を基準値とするものがあるが、私が使っているconvertでは0が基準。バージョンの問題か?

◎コントラストの変更
構文)convert ±contrast <input-file> <output-file>
用例)convert -contrast myphoto.jpg myphoto2.jpg (コントラストをやや弱くする)
コントラストを値で指定することはできない。強弱は、±contrastの回数で指定する。「-」は弱く、「+」は強くなる。なお、資料によっては+/-の意味が逆のものもある。

◎グレイスケール化
構文)convert -colorspace Gray <input-file> <output-file>
用例)convert -colorspace Gray myphoto.jpg myphoto2.jpg
モノクロ化(2値化)には専用オプションがあるが、グレイスケールに関してはカラースペースで指定するしかないようだ。ちなみに、「Grey」ではなく「Gray」。なお、新しいImageMagickでは -type Greyscaleオプションで指定するのが一般的らしいが、OS/2版は非対応。

なお、OS/2ネイティブの同種のツールとしてGBMがあるが、@Jpegが扱えないのでいったん他ツールでGIFに変換してから処理をする必要がある、Aリサイズの結果が汚い、の二つの欠点を抱えている(Warp 3に添付されていたバージョン)。また、奇麗にリサイズできるツールとしてはoutjpegもあるが、これは1/2、1/4、1/8の3種の縮小比率しか指定できず、ピクセル単位でのリサイズが不可能。REXXで一括処理をするときなどには、やはりImageMagickが最も優れている。

  GBMはその後バージョンアップされ、2008年2月現在の最新バージョンは1.54(Hobbesより入手可能)。このバージョンではJpegなどもサポートされているようだが、実際に使用してはいないので、機能は未チェック。

【重要】GBM v.1.76を使用してみたが、機能的にはOS/2版ImageMagick(2004年版)よりもかなり上であることが判明した。特に、テキスト形式のPGMやPPMなどにも変換できるので、画像をスクリプトで処理するときには極めて強力なツールになる(⇒ImageMagickでもテキスト出力自体は可能だった)。また、ImageMagick後継?のGraphicsMagickはOS/2でも1.3.19(2014年版)が使用できる。OS/2版のImageMagickは余りに古すぎるので、早めにこれらに乗り換えるべきだろう。(2014.05.24)

●ImageMagickのidentify (2007.12.10)

GIF画像のデータを取得する場合、縦横サイズのあとに+0+0といったような、オフセットがついてしまう。
  H:\CGTemp\temp\1871.GIF 480x640+0+0 DirectClass 84kb GIF 2s
しょうがないので、
  PARSE VAR st tmp xsize 'x' ysize dummy
  if POS('+',ysize)>0 then ysize=left(ysize,pos('+',ysize)-1);
てなカンジオフセットを取ること。 ちなみに、-size geometryオプションは、縦横サイズが不明のrawファイルの情報を取得する場合に使用するオプションで、こちらから明示的に800x600のようにサイズ指定をするものらしい。

なお、identifyを使ってスクリプトを書く際には、tmpという変数名は使わないこと。 どうやら、環境変数か何かとして使用しているようで、中身が壊れるよ。 わたしゃ、tmpにテンポラリファイル名を指定してデータを書き出すようにしたら、 何と、tmpの中身が画像ファイル名にすり変わっていて、画像を壊しちまった…(T_T)

●グレイスケール画像のフルカラー化

PMViewでgray-scaleの画像を表示すると、パレットの再配置のためか、二度描画してしまう。これが非常に欝陶しい。そこで、色空間を変換して、gray-scaleの画像をRGB full-colorに再配置してしまいたい。PMViewのColorメニューからGray scale (8bit) → RGB Deep color (24bit)という変換をするのは簡単だが、量が多いと面倒だ。

そこで、ImageMagickを使ってバッチ処理を試みたのだが、これがなかなかうまいこといかない。関係のありそうなオプション(-colors、-depth、-colorspace)をいろいろいじってみたが、ことごとく失敗した。仕方ないので、物凄く卑怯な方法でその場を糊塗することにした。すなわち、全体にごく薄い色(ここではBlueを1/255)を乗せることで、グレースケール画像を無理矢理カラー画像に変換してしまうという方法だ。ま、肉眼では色被りはほとんどわからないが、いかんせん情けない(;_;)

/* fullcolr.cmd  2005.12.25             */
/* Gray-scale(GIF) => Full-colors(Jpeg) */
Call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
Call SysLoadFuncs

/* ここではGIF→Jpeg変換をしているが、画像フォーマットは任意に指定できる。*/
/* Jpeg→Jpeg変換も可能(元ファイルへ上書きされる)。*/
call SysFileTree '*.gif',file,'OF'

Do n=1 to file.0
  fname=FILESPEC("NAME",file.n);
  PARSE VAR fname body '.' ext
  inp_file=fname
  out_file=body||'.jpg'
  'convert -colorize 0/0/1 -colorspace RGB' inp_file out_file
End;

●透明GIF

PMView 1.05のGIFセーブオプションで指定できる。

【逆襲のOS/2目次】 【ホーム】