とにかく奥が深い。何かやろうとするたびに、膨大なbackgroundに押し潰されそうになる。

*フォーマット [#o31398be]
画像の持つ情報量は多いので、ファイルの形式としては何らかの圧縮を施すのが通例であり、その方法の違いなどにより様々なファイル形式が存在する。一般に、写真画像ならjpegが適し、白の背景に黒の三角形を描きました、みたいなエッジのきいた人工的な図形ならPNGの方が適する場合が多い。
-[[ウェブで用いられる画像形式について。:http://www.marguerite-site.com/Nihongo/Labo/Image/index.html]]
-[[画像圧縮アルゴリズム (5) LZ法:http://www2.starcat.ne.jp/~fussy/algo/algo8-5.htm]]
-[[離散コサイン変換:http://laputa.cs.shinshu-u.ac.jp/~yizawa/InfSys1/advanced/dct/]]


*色とデータ量 [#r5756ed4]
一般的なPC上で、色は赤・緑・青(RGB)の各々の強度(加色混合)で表現される。各色の強度をどれだけ細かく制御するかで、表現できる色の数が決まる。

最近のPC上では約1677万色を区別して発色することが容易に可能で、これは大体人間の識別できる色数の限界といわれているらしい。この意味において、発色「数」に関してはPCまわりの技術は充分な水準に達しているといえる(無論、色空間の変換やらモニタの較正やら、他に考慮すべき事項もまだ沢山あるが、とりあえず「数」だけは充分)。

1677万とは 256*256*256=(2^8)^3 である。RGBに各々256種類(8bit)の情報を割り振ることによって実現される。つまり、ひとつの点の色を表現するのに 8bit + 8bit + 8bit = 24bit のデータ量が必要なわけである。このことから「1677万色の発色 」を24bitカラーと称することもある。True Colorと呼ばれているものも同様の意味を持つ。32bit PC上のデータ処理の観点からは、嘘データを8bitつめこんで、32bit/点 として扱う方が効率がよいらしい(アライメントの事情だかなんだか。よくわからん)。故に、32bitカラーと呼ばれているものも、色の数としては24bitカラーと変わらない。

これに対し、6万5千色を扱うHigh Colorあるいは16bitカラー(2^16=65536)と呼ばれるものもある。これはRとBを5bit、Gを6bitで表現している。業務用機器では、RGB各々10bitで表現している(2^(10+10+10)=1073741824 種類の発色ができる)ものもあるらしい。

以下参考文献。
-[[PC View:http://www.pc-view.net/]]より[[RGB:http://www.pc-view.net/Help/manual/0270.html]]
-[[色色雑学:http://konicaminolta.jp/entertainment/colorknowledge/index.html]] すごい!

**グレースケール [#v465ca1b]
モノクロ画像だと色の情報は失われるが、データ量も小さいため、RGBをモノクロに変換したいこともままある。しかしこの変換も一筋縄ではいかず、色々と方式があって混乱したが、幾つかのすばらしい解説のおかげで理解がちょっぴり深まった。
-[[osakana.factory - グレースケールのひみつ:http://ofo.jp/osakana/cgtips/grayscale.phtml]]
-[[ISP imaging-developers - 色変換式集:http://image-d.isp.jp/commentary/color_cformula/index.html]]
-[[YUVフォーマット及び YUV<->RGB変換:http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html]]


*BMP [#k3df96f6]
ビットマップ。文字通り、座標の各点(ビット)の色をSerialに記録(マップ)したもので、概念はとてもわかりやすい一方でデータ量はかなり多くなってしまう。

単純であるがため、歴史のある形式である。その結果、細かく仕様の異なるものが混在しているようで、全貌の把握にはなかなか骨が折れる。

-[[WisdomSoft:http://wisdom.sakura.ne.jp/]]の[[標準 Windows API:http://wisdom.sakura.ne.jp/system/winapi/win32/index.html]]より[[DIB ファイルヘッダ:http://wisdom.sakura.ne.jp/system/winapi/win32/win114.html]]などなど
-[[ビットマップファイルの構造:http://hp.vector.co.jp/authors/VA023539/tips/bitmap/001.htm]]
-[[BMPファイルを32ビットDIBとして読み込む:http://www13.plala.or.jp/kymats/study/MULTIMEDIA/load_dib32.html]]
-[[第3回 BitmapをVC++で扱うヒント:http://cutie.dip.jp/pc/image/3.php]]

**幅とデータ量の検証 [#v588ef3a]

***preface [#p8a8d312]
ビットマップを(数学でいうところの)行列として捉える。このとき行数は画像の高さ、列数は画像の幅を表す(単位はpixel)。上下の区別をとりあえず無視すると、ビットマップの画像データの並び方は次のように表現できる。
 (第1行のデータ)(第2行のデータ)(第3行のデータ)...
つまり、横方向の1ラインをまずはドドっと格納し、そして次のラインをドドっと・・・という具合である。この時、ビットマップ形式のシキタリでは、''1行(1ライン)あたりのbyte数は4の倍数でなくてはならない''そうだ。画像の幅なんてのは千差万別なので、不幸にして生データ(pixel数ではない)が4の倍数にならないなんてことはザラにあるわけだが、その時は行の末尾に嘘データ(ゼロ)を詰めて無理矢理に一番近い4の倍数にしてしまうらしい。実感を得るために検証してみた。(ただの自己満足です)

***準備と予想 [#r8bb16cb]
最も使用頻度の大きいであろう24bitカラーのビットマップを、幅を1pixelずつ変えて保存し、各々のファイルサイズを比較するという作戦である。

素材としてC:\WINNT(windows2000)にある「フィッシング.bmp」を使う。Photoshopでサイズを128pixel(横) x 64pixel(縦)にし、さらに24bitカラーとした。

#ref(save_dialog.png)

この時1行あたりのデータ量は、1pixelあたり3byte(24bit)であるから
 128 x 3byte = 384byte
であり、4で割切れる(ので嘘データ不要)。この時のファイルサイズを起点とする。さて幅を1pixel増やすと1行あたり
 129 x 3byte = 387byte
であって4で割切れない。割切れるように嘘データを詰めて1行あたり388byteとなるならば、全体として
 (388 - 384)byte x 64 = 256byte
のファイルサイズの増加となるはずである。同様にして、
 130 x 3byte = 390byte ==> (392 - 384)byte x 64 = 512byte ==> 512byteの増加
 131 x 3byte = 393byte ==> (396 - 384)byte x 64 = 768byte ==> 768byteの増加
 132 x 3byte = 396byte ==> (396 - 384)byte x 64 = 768byte ==> 768byteの増加
 127 x 3byte = 381byte ==> (384 - 384)byte x 64 = 0byte ==> 0byteの増加
となるはずである。127と128、131と132のファイルサイズが変わらないあたりで4の倍数の実感が沸くはずである。

***結果 [#qb5b2124]
予想通りとなった。知ってる人からするとバカらしい検証だろうが、うまくいったので満足。

#ref(127dlg.png)
&br;
#ref(128dlg.png)
&br;
#ref(129dlg.png)
&br;
#ref(130dlg.png)
&br;
#ref(131dlg.png)
&br;
#ref(132dlg.png)

*PNG [#h1252d19]

Portable Network Graphics のことで、GIFの後継として開発されたそうだ。

**ライブラリ [#h5709eca]

プログラムからPNGを扱うためには[[zlib:http://www.zlib.net/l]]と[[libpng:http://www.libpng.org/pub/png/libpng.html]]が必要となる。ソースもバイナリも手に入るが、ソースを持ってきてもVisual Studio用のプロジェクトが付属するのでビルドは楽である。プロジェクトを開いて ビルド => アクティブな構成の設定 から好きなものを選ぶだけでよい。
-[[bmp2png & png2bmp:http://hp.vector.co.jp/authors/VA010446/software/b2psrc.html]]
-[[PNG利用術:http://www5.cds.ne.jp/~kato/png/]]
-[[PNGを読み込む(VC++でlibpngを使用する):http://hp.vector.co.jp/authors/VA016379/cpplib/libpng.htm]]
-[[libpngについて:http://estset.d.fiw-web.net/unix/libpng.html]]
-[[MNG/PNGを使ってみる:http://www.jah.ne.jp/~naoyuki/Writings/MngPng.html]]


**PNGファイルフォーマット [#h064f0e5]
-[[倉庫という名の作品展:http://depot.c--v.net/yaezakura.php/docs/prog/png]]
-[[Portable Network Graphics (PNG) Specification (Second Edition):http://www.w3.org/TR/2003/REC-PNG-20031110/]]



*GDI+ [#u84caed6]
Windowsにおいて、標準の画像フォーマットは所謂「ビットマップ」であるが、それ以外のjpegといったフォーマットの方が巷で専ら使用されている。GDI+は、そういった様々のフォーマットの画像(BMP, GIF, JPEG, PNG, TIFF, EMF)を扱うためのライブラリ。(だそうだ。まだ使ってない)

-[[GDI+に関するメモ:http://www.nilab.info/megabbs/readres.cgi?bo=computer&vi=1093051600]]
-[[GDI+の導入:http://lamoo.s53.xrea.com/develop/gdiplus/gdiplus.html]]
-[[第335章 GDI+の基礎 その1(猫でもわかるプログラミングより):http://www.kumei.ne.jp/c_lang/sdk4/sdk_335.htm]]
-[[第336章 GDI+の基礎 その2(猫でもわかるプログラミングより):http://www.kumei.ne.jp/c_lang/sdk4/sdk_336.htm]]
-[[GDI+ Programming Note:http://park17.wakwak.com/~dragoon/gdiplus1.htm]]
-[[GDI+ と VC++ と日本語:http://weblog.rukihena.com/archives/2005/02/gdi_vc.html]]


platformSDKが必要みたいだ。
-[[Windows Server 2003 PSDK Full Download with Local Install(Windows 2000でもこちらから導入するらしい):http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm]]
-[[Visual C++ Toolkit + Platform SDK のインストールとテスト:http://homepage1.nifty.com/kazubon/progdoc/poor/vctoolkit.html]]

こんな感じのコードでjpegがピクチャコントロールに表示できた。初期化などはすでに終わっているものとする。

 const HWND hWndPict = GetDlgItem(hWnd, IDC_PICT);
 RECT Rect;
  GetClientRect(hWndPict, &Rect);
 const int width = Rect.right - Rect.left;
 const int height = Rect.bottom - Rect.top;
 
 setlocale(LC_ALL,"");
 HDC hdc = GetDC(hWndPict);
 Graphics MyGraphics(hdc);
 Image myImage(filename); // WCHAR* filename
 MyGraphics.DrawImage(&myImage, 0, 0, width, height);
 
 ReleaseDC(hWndPict, hdc);