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