とにかく奥が深い。何かやろうとするたびに、膨大なbackgroundに押し潰されそうになる。
 
 *EXIF [#s4ce1589]
 デジカメなんかがjpegに各種情報を埋め込むための仕様なのだそうだ。どの受光素子が「画像の左上」か、なんて(カメラを縦向きで撮ったかどうか)なんかも記録してくれるので便利。でもどうやらメーカーごとに「方言」があるみたいなのが困る。
 
 -[[Exif形式の画像ファイル解説:http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif.html]]
 
 *jpeg [#fbceec51]
 
 風景、人物写真などに適したフォーマットで、非常に広く普及している。
 
 **IJG [#qed3ec81]
 [[IJG:http://www.ijg.org/]]という所が総本山っぽい雰囲気である。スタンダードっぽい[[ライブラリ:http://www.ijg.org/files/jpegsrc.v6b.tar.gz]]を提供しておった。関連webページは以下。
 -[[Independent JPEG Group's JPEG software release 6b with x86 SIMD extension for IJG JPEG library version 1.02:http://cetus.sakura.ne.jp/softlab/jpeg-x86simd/jpegsimd.html]]
 -[[オープンソースを使った JPEG 操作:http://www.amy.hi-ho.ne.jp/jbaba/jpeg1.htm]]
 -[[Windows Programming Tips:http://tanack.hp.infoseek.co.jp/program.html]]
 
 
 *フォーマット [#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);
 
 *jpeg [#fbceec51]
 
 風景、人物写真などに適したフォーマットで、非常に広く普及している。
 
 **IJG [#qed3ec81]
 [[IJG:http://www.ijg.org/]]という所が総本山っぽい雰囲気である。スタンダードっぽい[[ライブラリ:http://www.ijg.org/files/jpegsrc.v6b.tar.gz]]を提供しておった。関連webページは以下。
 -[[Independent JPEG Group's JPEG software release 6b with x86 SIMD extension for IJG JPEG library version 1.02:http://cetus.sakura.ne.jp/softlab/jpeg-x86simd/jpegsimd.html]]
 -[[オープンソースを使った JPEG 操作:http://www.amy.hi-ho.ne.jp/jbaba/jpeg1.htm]]
 -[[Windows Programming Tips:http://tanack.hp.infoseek.co.jp/program.html]]