• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:PNGを24bppBMPに変換したいのですが・・。)

PNGを24bppBMPに変換する方法とは?

このQ&Aのポイント
  • libpngを使用してPNGを24bppBMPに変換する方法について詳しく教えてください。
  • PNGを24bppBMPに変換するためにはlibpngを使用しますが、うまくいかない問題が発生しています。具体的なバグの内容と解決策を教えてください。
  • PNGを24bppBMPに変換するためには、libpngを使用してPNGファイルを読み込み、BMPファイルに書き込む必要があります。しかし、png_create_read_structの呼び出し時にエラーが発生しているようです。このエラーの解決方法を教えてください。

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

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

 こんばんは。  もっと色々な設定をしなければならないのでは。  付け焼刃で書いたのでエラー処理がいい加減ですが、以下参考程度に。 #include<windows.h> #include "png.h" #pragma comment(lib, "libpng.lib") #pragma comment(lib, "zlib.lib") static void Save(FILE* fpOut, png_bytep image, png_uint_32 width, png_uint_32 height, png_uint_32 campusline) { const png_uint_32 imageSize = campusline * height; BITMAPINFOHEADER bmih = {sizeof(bmih)}; BITMAPFILEHEADER bmfh = {0}; bmfh.bfType = 0x4d42; bmfh.bfOffBits = sizeof(bmih) + sizeof(bmfh); bmfh.bfSize = bmfh.bfOffBits + imageSize; bmih.biWidth = width; bmih.biHeight = height; bmih.biPlanes = 1; bmih.biBitCount = 24; bmih.biCompression =BI_RGB;//無圧縮形式 bmih.biSizeImage =0;//BI_RGBをセットした場合、0が好ましいとMSDNに書いてあった。 //ヘッダファイルを書き込む fwrite(&bmfh,sizeof(bmfh), 1, fpOut); fwrite(&bmih,sizeof(bmih), 1, fpOut); fwrite(image, imageSize, 1, fpOut); } png_uint_32 PNGtoBMP(const char* inFileName, const char* outFileName) { png_structp png_ptr = NULL; png_infop info_ptr = NULL; png_bytep image = NULL; png_bytepp row = NULL; png_uint_32 width = 0; png_uint_32 height = 0; png_uint_32 campusline = 0; png_uint_32 y = 0; png_int_32 bit_depth = 0; png_int_32 color_type = 0; png_int_32 interlace_type = 0; png_uint_32 result = 0; FILE* fpIn = fopen(inFileName, "rb"); FILE* fpOut = fopen(outFileName, "wb"); if(fpIn == NULL) { MessageBox(NULL,"fopen error", "in file error",MB_OK); goto clean_up; } if(fpOut == NULL) { MessageBox(NULL,"fopen error", "out file error", MB_OK); goto clean_up; } png_ptr = (png_structp)png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(png_ptr == NULL) { MessageBox(NULL,"error", "png_ptr error", MB_OK); goto clean_up; } // info_ptr構造体を確保・初期化します info_ptr = png_create_info_struct(png_ptr); if(info_ptr == NULL) { MessageBox(NULL,"error", "info_ptr error", MB_OK); goto clean_up; } // libpngにfpを知らせます png_init_io(png_ptr, fpIn); // PNGファイルのヘッダを読み込みます png_read_info(png_ptr, info_ptr); // IHDRチャンク情報を取得します png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); //以下はその他フォーマットの違いを修正する為の設定です if(color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr); if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand(png_ptr); if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr); if(bit_depth > 8) png_set_strip_16(png_ptr); if(color_type & PNG_COLOR_MASK_ALPHA) png_set_strip_alpha(png_ptr); if(color_type == PNG_COLOR_TYPE_GRAY) png_set_gray_to_rgb(png_ptr); //設定を反映します png_read_update_info(png_ptr, info_ptr); //もう一度IHDRチャンク情報を取得します png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); //メモリ上の1Line(修正値も含む) campusline = (int)((width * 24 + 31) / 32.0) * 4; // 以下は2次元配列を確保します image = (png_bytep)calloc(campusline, height); if(image == NULL) { MessageBox(NULL,"error", "image out memory", MB_OK); goto clean_up; } //縦の配列を確保します row = calloc(sizeof(png_bytep), height); if(row == NULL) { MessageBox(NULL,"error", "row out memory", MB_OK); goto clean_up; } //y軸を逆転して代入します for(y = 0; y < height; ++y) { const png_uint_32 pos = ((height - 1) - y) * campusline; row[y] = &image[pos]; } //rgb->bgrの並びにするように命じます png_set_bgr(png_ptr); // 画像データを読み込みます png_read_image(png_ptr, row); //終了です png_read_end(png_ptr, info_ptr); //ビットマップにセーブします Save(fpOut, image, width, height, campusline); result = 1; clean_up: // 後始末です free(image); free(row); if(png_ptr && info_ptr) png_destroy_read_struct(&png_ptr, &info_ptr, NULL); else if(png_ptr && !info_ptr) png_destroy_read_struct(&png_ptr, &info_ptr, NULL); else //此処に来る事があってはおかしい if(fpIn) fclose(fpIn); if(fpOut) fclose(fpOut); return result; } int main() { PNGtoBMP("pngtest.png", "bitmap.bmp"); return 0; }

ringist
質問者

お礼

お疲れ様です 参考コードありがとうございました 大変参考になりました。 あれからデバッグを繰り返したのですが png_ptr = (png_structp)png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); のところで必ず動作が中止(実行時エラー)されてしまいます。 もしかするとVISTA SP1とlibpngの相性が悪いのかもしれません。 ご回答ありがとうございました。

関連するQ&A