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ででばっかが止まります。
お忙しい中恐縮ですがどなたかご教授お願いします。
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;
}
お疲れ様です 参考コードありがとうございました
大変参考になりました。
あれからデバッグを繰り返したのですが
png_ptr = (png_structp)png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
のところで必ず動作が中止(実行時エラー)されてしまいます。
もしかするとVISTA SP1とlibpngの相性が悪いのかもしれません。
ご回答ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) Excel vbaについての質問 3 2023/04/18 16:14
- PHP 共通の処理をまとめる方法がわからないのでアドバイスお願いします。 1 2022/12/19 20:20
- JavaScript clear機能を失わずにファイルアップロード機能を作成したい 3 2023/06/10 16:12
- HTML・CSS CSSが効かずどのように指定すれば良いか分からないのでアドバイスお願い致します 2 2023/06/07 12:25
- PHP imageフォルダに、画像をリサイズして保存する時のファイル名を変更したい 1 2023/05/30 11:39
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- その他(プログラミング・Web制作) pythonで、tkinterとpillowの組み合わせ 2 2022/08/16 17:42
- JavaScript アップロードファイルの種類によって処理を分岐させたいのですが書き方が分からずアドバイスお願いします 4 2023/06/17 19:12
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- UNIX・Linux zshの文字列置換機能 5 2023/07/23 18:53
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語でwin32apiを使ってnotepa...
-
PNGを24bppBMPに変換したいので...
-
DOSのdirコマンドで思うように...
-
ポインター引数の関数でコンパ...
-
10Mバイトて文字数に すると何...
-
COBOLのCOMP形式について
-
char str[256]の256の意味は?
-
UTF-8で5~6バイトになる文字コ...
-
Excel 1セル当りの文字数が2...
-
エクセルシート名の制限を変更...
-
バイナリとBCDコード
-
Excel VBA メール作成について ...
-
「1TB」のHDDに日本語は何字入...
-
CGIを勉強しています。¥n(改...
-
バイト列とバイナリ列の違いが...
-
テキストファイルの結合について
-
10個の実数に対する降順ソート...
-
C言語において2バイト文字を検...
-
Rstudioによるテキストマイニン...
-
半角、全角の判別方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語でwin32apiを使ってnotepa...
-
デバイスコンテキストに書いた...
-
PNGを24bppBMPに変換したいので...
-
DOSのdirコマンドで思うように...
-
エラー「書き込み中にアクセス...
-
JavaScriptの条件分岐について(...
-
細線化のプログラム
-
python についての質問です
-
VBAの計算について
-
このプログラムはどういった事...
-
ポインター引数の関数でコンパ...
-
10Mバイトて文字数に すると何...
-
UTF-8で5~6バイトになる文字コ...
-
エクセルシート名の制限を変更...
-
COBOLのCOMP形式について
-
stable diffusionのエラー
-
ビットスワップとバイトスワッ...
-
char str[256]の256の意味は?
-
Excel VBA メール作成について ...
-
バイナリとBCDコード
おすすめ情報