• ベストアンサー

png画像の縦一列を効率よく読み込むには

libpngを使用してpng画像をデコードしています。 png画像の最初のピクセルを一列読み込みたいのですが、libpngの1行単位のデコードだと結局全てデコードすることになると思います。 png画像のデコードはCPU負荷が高いので縦1列効率よくデコードしたいのですが何か全てデコードしない方法をご存じの方がいらっしゃればお教え下さい。 最悪 png_read_rows()を改造するとか、libpngを使用しないとか別の方法でも構いません。 よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

pngの画像形式的に、それ以上は一般的には無理です。 画像データ本体はDeflate形式で圧縮されているため、デコードは先頭からやっていく必要があります。また、圧縮済みのデータから、圧縮前のnビット先のデータを探すことも(デコードしなければ)無理です。 画像自体の圧縮方法を工夫すれば、可能性は若干あるような気もしますが、そこまではしませんよね: # 画像本体のデータ構造 IDAT を行ごとに作成する # デコード時は行ごとに先頭からちょっとずつデコードする # (一応png形式に違反していない)

chinchilla
質問者

お礼

詳細な回答をありがとうございました。 さすがに既存のpng(インタレスなどは対応しませんが)を対象にする必要がありますが、 専門的で貴重なご意見ありがとうございます。 大変助かります。 libpngの I/Fにはないようなので、後は自分で libpngを改造して多少でもデコード時間を削減できるかどうか、というところですね。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • PNG画像のファイルサイズを落とす方法

    1.32MBのPNG画像を0,9MBぐらいまで多少劣化してもいいのでPNG画像のままファイルサイズを落とす方法はありますか。 アメブロのヘッダーに載せようと思っております。 画像サイズを変更せずにファイルサイズを落としたいのです。 Paint.netでコラージュを作成して1300×900ピクセルから980×678ピクセルに画像サイズを落としたのですがそのファイルサイズが1.32MBなのです。 このコラージュの背景を透明にしたいので、PNGで保存したいのです。GIFでは画像が荒すぎます。 誰かわかる方よろしくお願いいたします。

  • PNGを24bppBMPに変換したいのですが・・。

    libpngを用いて PNGを24bppBMPに変換したいのですがうまくいきません。 #include "png.h" #pragma comment(lib, "libpng.lib") void PNGtoBMP(char *filename) { FILE *fpt,*fpt_output; png_structp png_ptr; png_infop info_ptr; unsigned long width, height; int bit_depth, color_type, interlace_type; unsigned char **image; int i,j; MessageBox(NULL,"PNG End","PNG End",MB_OK); fopen_s(&fpt,filename, "rb"); if(fpt==NULL) { MessageBox(NULL,"fopen_s error","error",MB_OK); } else { // まずファイルを開きます fopen_s(&fpt_output,"PNG.bmp","wb"); png_structp png_ptr = png_create_read_struct ( PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn); #if 0 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); #endif #if 0 info_ptr = png_create_info_struct(png_ptr); // info_ptr構造体を確保・初期化します png_init_io(png_ptr, fpt); // libpngにfpを知らせます png_read_info(png_ptr, info_ptr); // PNGファイルのヘッダを読み込みます png_get_IHDR(png_ptr, info_ptr, &width, &height, // IHDRチャンク情報を取得します &bit_depth, &color_type, &interlace_type, NULL, NULL); image = (png_bytepp)malloc(height * sizeof(png_bytep)); // 以下3行は2次元配列を確保します for (i = 0; i < height; i++) image[i] = (png_bytep)malloc(png_get_rowbytes(png_ptr, info_ptr)); png_read_image(png_ptr, image); // 画像データを読み込みます int campusline=(int)((width*24+31)/32.0)*4;//メモリ上の1Line(修正値も含む) int modification=campusline-(int)((24/8.0)*width); BITMAPINFOHEADER bmih; BITMAPFILEHEADER bmfh; //RGBQUAD rgbquad; DWORD filesize,bmfhsize,bmihsize; bmfhsize=sizeof(bmfh); bmihsize=sizeof(bmih); //rgbquadsize=sizeof(rgbquad); filesize=bmfhsize+bmihsize+(3*width+modification)*height; ::ZeroMemory(&bmfh, bmfhsize); ::ZeroMemory(&bmih, bmihsize); bmfh.bfType=0x4d42; bmfh.bfSize=filesize; bmfh.bfReserved1=0; bmfh.bfReserved2=0; bmfh.bfOffBits=bmfhsize+bmihsize; bmih.biSize=bmihsize; bmih.biWidth=width; bmih.biHeight=height; bmih.biPlanes=1; bmih.biBitCount=24; bmih.biClrUsed=0; bmih.biCompression=BI_RGB;//無圧縮形式 bmih.biSizeImage=0;//BI_RGBをセットした場合、0が好ましいとMSDNに書いてあった。 bmih.biXPelsPerMeter=0; bmih.biYPelsPerMeter=0; bmih.biClrImportant=0; //ヘッダファイルを書き込む //fwrite(&bmfh,sizeof(unsigned char),bmfhsize,fpt_output); //fwrite(&bmih,sizeof(unsigned char),bmihsize,fpt_output); #if 0 //ここで最終的に書き込みを行う。 for(i=0;i<height;i++) { fwrite(&image[i][0],sizeof(unsigned char),3*width,fpt_output); //修正値の代入 for(j=0;j<modification;j++) { fwrite("\x000",sizeof(unsigned char),1,fpt_output); } } #endif for (i = 0; i < height; i++) free(image[i]); // 以下2行は2次元配列を解放します free(image); png_destroy_read_struct( // 2つの構造体のメモリを解放します &png_ptr, &info_ptr, (png_infopp)NULL); #endif fclose(fpt); fclose(fpt_output); } } *同一ディレクトリに、libpng.lib, libz.lib(zlib.libではない) があります。また、libpng12.dllも要求されたので、同一 ディレクトリに配置しています。 バグは png_structp png_ptr = png_create_read_struct ( PNG_LIBPNG_VER_STRING, (png_voidp) の時点で起きていて これを書いてビルドして実行すると エラーになり open.cででばっかが止まります。 お忙しい中恐縮ですがどなたかご教授お願いします。

  • 「すべてのプログラム」を縦一列に表示する方法

    WinXP、SP3を使っています。「スタート」から「すべてのプログラム」を開くとプログラムの数が多すぎて表示が切れてしまいます。 このプログラムをを小さく表示して一覧できる方法か、または縦一列(矢印で繰り上がっていけば全部表示可能と思います)に表示する方法を知りたいと思います。なんか方法があったと記憶しているのですが、どなたか教えていただければ幸いです。 よろしくお願いします。

  • PNG画像を透明化したい

    使っている賀状ソフトがPNG自動透過に対応していないようなんですが透過処理のしてあるPNG画像を使用できる方法ありますか? または他のソフトでそのように加工できるものはありますか? その場合、ワードとか一太郎とかフォトショップとか持っていないので出来ればフリーのソフトがよいです。 ちなみに今使っている賀状ソフトは「筆自慢Ver.12」です。 よろしくお願いします。

  • iMovie pngの画像の透明部分が真っ黒になる

    iMovieのpngの画像の読み込み方についての質問です。 iMovieにPhotoshopで背景を透明にした画像を読み込みたいと思い、 pngで保存し読み込んだところ、透明にした部分が真っ黒になって表示されました。 pngの画像は、Photoshopで「Web用およびデバイス用に保存」でPNG-24、透明部分にチェックを入れて保存しました。 どのような方法で保存すれば、背景が真っ黒にならずに画像を読み込むことができるのでしょうか? iMovieは10.0.3、PhotoshopはCS5を使用しています。 よろしくお願い致します。

    • 締切済み
    • Mac
  • Acrobat6で保存するPNG画像の解像度

    wordのdocファイルをpdfにしたものを画像にして利用するために、AcrobatPro6を用いてpdfファイルをページ毎にpngファイルに保存しています。 すると、同じサイズのページでもページによってピクセル数がまちまちに保存されてしまいます。 たくさんの画像をトリミングする必要があるため、できれば元のページが同じものはみな同じピクセル数の画像を生成したいのですが、良い方法はありますでしょうか。

  • PNG画像の大きさ取得(エクセルvba)

    PNG画像の幅と縦の取得ができなくて困っています。 PNG以外でしたら、下記の関数に画像ファイルのパスを渡せば求められるのですが、 LoadPicture関数がPNG未対応のようです。 Sub subGetPicSize(PicPath As String) Dim P Set P = LoadPicture(PicPath) MsgBox CLng(P.Width * 0.0378) & "×" & CLng(P.Height * 0.0378) End Sub 画像変換ツールでPNGをBMPなどほかの形式にすれば、大きさを求められますが、よりよい方法を知っていれば教えてください。 宜しくお願いします。

  • 16ビットグレースケールの画像を描画させたい。

    16ビットグレースケールの画像を描画させたい。 こんにちは。 Photoshopで16ビットグレースケールのPNGファイルを作り、 それをlibpngを使って読み込むプログラムを書きました。 16ビットRGBではなくグレースケールです。1ピクセルの 情報は0~65535です。 640*480の画像で例えるならば、640*480*2の大きさで CreateDIBSection関数を使って作成しているだけなので Bitblt関数を使って描画させようとしても、16ビットRGB として描画しようとするので正しく表示されません。 これを正しく描画させる方法はありませんでょうか? さらにLineToやRectangle等で編集もしたいのですが、 可能でしょうか?

  • jpg画像の縦と横のピクセル単位サイズの取得

    perlでjpg画像の縦、横のピクセルを取得する方法が解りません。 ピクセル取得後、計算して表示したいのですが。 よろしくお願いします。

    • 締切済み
    • CGI
  • Excel表を一列にしたい

    7列の表を一列に直したいのです。 A1,A2,A3・・B1,B2とあるものを別のシートに A1→A1,B1→A2,C1→A3・・・と、すべてを一列にするにはどうしたらいいでしょうか? Offsetを使うことも考えましたが、あまり効率がいいとも思えず、 マクロもどうすればいいかがわかりません。 表には数値だけでなく文字列もあるので、抽出はいらないのですが、 作業で一列になっていないと不便なのです。 いい方法はありませんか? Excelは2003です。