#author("2018-10-31T17:43:04+09:00","default:pbcglab_user","pbcglab_user") 画像ファイルフォーマットのC,C++での取り扱い. ---- #contents ---- *Windows Bitmap [#p900218b] 単純にビットマップ画像というと,色を表すピクセルを格子状に並べて画像を表現したもの(相対するものにベクタ画像がある)であるが,Windows Bitmapというと Windows標準の画像ファイル形式を指す.拡張子はbmp. ***種類 [#bac7a6ab] Windows BitmapはOS/2用とWindows用に大きく分けることができ, 細かくは以下の5種類が存在する. -OS/2(COREタイプ) -OS/2 V2(INFO2タイプ) -Windows V3(INFOタイプ) -Windows V4(V4タイプ) -Windows V5(V5タイプ) 一般的にはINFOタイプが用いられている. V4はINFOにカラーマネジメント,V5はさらにカラープロファイルを追加した形式. 基本的には無圧縮で使われるが,Windows V3-5ではRLE,JPEG,PNG圧縮が規定されている. 各形式のヘッダ構成は[[WikipediaのBMP file format:http://en.wikipedia.org/wiki/BMP_file_format]]参照. ***コード例 [#m3dfc7d3] Windows Bitmapファイルの読み込み,書き出しを行う関数を実装したヘッダファイルを以下に置く. #ref(rx_bitmap.h) 注意事項 -OS/2(V1), Windows(V3,V4,V5)の非圧縮BMPに対応 -ビットフィールド付きビットマップ,カラーパレット付きBMPの読み込み(書き込みは未対応)に対応.ただし,サンプルとなるファイルがなかったので動作は未確認 -RLE, JPEG, PNG圧縮は未対応 -V4,V5のカラーマネジメント,プロファイルは未対応 -2016年2月18日更新 : 横の解像度が4nでないものに対応していなかったのを修正 *JPEG [#k44c8e85] JPEGはJoint Photographic Experts Groupによる非可逆圧縮画像フォーマット.圧縮率の高さからWeb,デジカメなど多くの場所で用いられている.デジカメでは記録時の情報(日付や画像の向き,カメラの種類など)を格納できるように拡張されたEXIF(Exchangeable image file format)がよく用いられている.拡張子はjpg,jpeg,jpe,jfif,jfi,jifの6つ. ***特徴 [#i4597f79] DCT(離散コサイン変換)による周波数領域への変換などにより非常に高い圧縮率(だいたい1/10〜1/100)を実現しているが,画像をブロックに分割した上でDCTを掛けているので,ブロックノイズと呼ばれるノイズが発生する.そのため,画像処理などを行う際の中間フォーマットには用いない方がよい.最終的にできた画像を公開するなどのときにJPEGに変換するのがよい. ***libjpegライブラリ [#mce7d177] [[libjpeg:http://www.ijg.org/]]はC言語で書かれたJPEGファイルの入出力ライブラリ.BMPと違い,JPEGファイルを読み書きするコードを自分で一から作るととても大変なので,こういったライブラリを用いた方がよい.以下にビルド方法とコード例を示す. ***libjpegのビルド [#a860237f] #include(build_libjpeg,title) ***コード例 [#z554c5f4] libjpegを用いてJPEGファイルの読み込み,書き出しを行う関数を実装したヘッダファイルを以下に置く. #ref(rx_jpeg.h) 使うときは,ライブラリファイルをリンクすること.VC++ならソースに以下のように記述しても良い #ifdef _DEBUG #pragma comment (lib, "libjpegd.lib") #else #pragma comment (lib, "libjpeg.lib") #endif *PNG [#bfdc43ea] PNGはPortable Network Graphicsの略で,可逆圧縮画像フォーマットである. 1995年頃にGIFフォーマット(当時Web上で非常に良く用いられていた可逆画像フォーマット)に使われている圧縮方式に特許問題が発生した.そのときに代替になるものとして開発された(Png is Not Gifという意味も). ただ,ブラウザが標準で対応しないことが多いなどもありGIFを完全に置き換えるとはならなかった. 拡張子はpng. ***特徴 [#rdcf2631] PNGは歴史的な経緯からGIFと比較されることが多いので,ここではGIFと比べた際の利点,欠点を挙げる. -フルカラーサポート : GIFは256色(8ビット)であったが,PNGは16ビットグレイスケール,24/48ビットRGBフルカラーに対応している. -アルファチャンネルのサポート : 8/16ビットアルファチャンネルが使える.GIFでは1色(透明が不透明で0か1)のみ. -ガンマ補正のサポート -2次元インタレース : GIFより早めに全体像が見える. -GIFより圧縮サイズが小さい : といっても5〜25%ぐらいらしいが. 欠点としては, -アニメーション(複数画像)は対応していない : ただし拡張フォーマット(MNG,APNG)でサポート. -圧縮・展開に時間がかかる その他の特徴は以下のページ参照. -[[A Basic Introduction to PNG Features:http://www.libpng.org/pub/png/pngintro.html]] PNGはJPEGほど圧縮率は高くないが,可逆圧縮なので画像が劣化しない.中間フォーマットなどに用いるのに最適である. ***libpngライブラリ [#qd256a41] [[libpng:http://www.libpng.org/pub/png/libpng.html]]はPNGファイルの入出力ライブラリ.以下にビルド方法とコード例を示す. ***libpngのビルド [#r7b53deb] #include(build_libpng,title) ***コード例 [#w9883484] libpngを用いてPNGファイルの読み込み,書き出しを行う関数を実装したヘッダファイルを以下に置く. #ref(rx_png.h) 使うときは,ライブラリファイルをリンクすること.VC++ならソースに以下のように記述しても良い #ifdef _DEBUG #pragma comment (lib, "libpngd.lib") #pragma comment (lib, "zlibd.lib") #else #pragma comment (lib, "libpng.lib") #pragma comment (lib, "zlib.lib") #endif *WebP [#labcf23d] [[WebP(ウェッピー):http://ja.wikipedia.org/wiki/WebP]]はGoogleが公開しているオープンな画像フォーマット. 動画フォーマットのWebMの静止画版. ***特徴 [#a97d960d] WebMで使われているVP8を使って圧縮し,RIFFを元にしたコンテナに格納している. 可逆,不可逆圧縮両方に対応し,可逆圧縮の場合,PNGより[[28%小さく:http://code.google.com/intl/ja/speed/webp/docs/webp_lossless_alpha_study.html#results]],不可逆圧縮の場合,同じクオリティのJPEGより[[25-34%小さい:http://code.google.com/intl/ja/speed/webp/docs/webp_study.html#exp1]]らしい. ***対応ソフトウェア [#v7592aca] WebP画像ファイルへの変換は,[[WebPのページ:http://code.google.com/intl/ja/speed/webp/]]のDownloadから,Precompiled WebP utilities and library をダウンロードするとエンコーダ(cwebp.exe)とデコーダ(dwebp.exe)が得られる.Windowsのエクスプローラのプレビューやフォトビューアーでみたい場合は,WebP Codec for Windowsをダウンロードして,インストールすればよい.また,当然ながらGoogle Chromeはネイティブに対応しているので,単純に画像を確認したいならば,ChromeにD&Dすればよい. ***libwebpライブラリ [#i59e1e2b] libwebpはGoogle codeで公開されているWebPを扱うためのライブラリ.以下にビルド方法とコード例を示す. ***libwebpのビルド [#s2e7cfb8] #include(build_webp,title) ***コード例 [#w9883484] libwebpを用いてWebPファイルの読み込み,書き出しを行う関数を実装したヘッダファイルを以下に置く. #ref(rx_webp.h) libwebpのソースに付属のサンプルを元にしている. 使うときは,ライブラリファイルをリンクすること.VC++ならソースに以下のように記述しても良い #ifdef _DEBUG #pragma comment (lib, "libwebp_a_debug.lib") #else #pragma comment (lib, "libwebp_a.lib") #endif *リンク [#s540a4f0] C/C++での画像入出力に使えそうなライブラリ - [[FreeImage:http://freeimage.sourceforge.net/]] : BMP,JPG,PNG,GIFといった基本的なものからRAW,WEBP,JPEG2000まで幅広い画像入出力が出来る.簡単な画像処理(色変換程度)はでき,OpenGLのテクスチャにも直接使える. - [[OpenCV:https://opencv.org/]] : 言わずと知れた画像処理系で最も有名なライブラリ.対応する画像フォーマットも[[多い:https://docs.opencv.org/3.0-beta/modules/imgcodecs/doc/reading_and_writing_images.html]]が画像入出力だけに使うには導入が少しめんどくさい.各種画像処理も行いたいならこっちがよい.