このドキュメントは「libpngを使ってみよう(読み込み編)」を読んでいる事を前提としています。まだ読んでない方は、先に読み込み編をお読みください。
読み込みが出来るようになったら、次は書き込みです。もちろん、ソースコードの頭に
|
#include "png.h" #pragma comment(lib, "libpng.lib") |
int SavePngFile(HWND hWnd){
FILE *fp = fopen("test.png", "wb");
if(!fp)return 0;
ktFileCloser ktfileclose(fp);
png_structp png_ptr;
png_infop info_ptr;
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr) return 0;
info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr){
png_destroy_write_struct(&png_ptr, png_infopp_NULL);
return 0;
}
ktPngWriteStructReleaser pngwritereleaser(png_ptr, info_ptr);
|
| png_structp png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn) | ||
| 引数: | user_png_ver | PNGのバージョンを指定します。PNG_LIBPNG_VER_STRINGを使っておけばいいです。 |
| error_ptr, error_fn, warn_fn | エラーが起こったときに呼び出される関数と渡されるデータです・・・が、今回は使用していません。NULLにしています。 | |
| 返り値: | 成功すれば正常なpng_struct *を返します。失敗した場合はNULL値になります。 | |
| int png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr) | ||
| 引数: | png_ptr_ptr | png_create_write_structで取得できたpng_struct *へのアドレスを指定します。 |
| info_ptr_ptr | png_create_info_struct(後述)で取得したpng_info *へのアドレスを指定します。一緒に閉じられます。 | |
int Width = GetDeviceCaps(hDesktopDC, HORZRES);
int Height = GetDeviceCaps(hDesktopDC, VERTRES);
BYTE *pBits;
BITMAPINFO bmpinfo = {sizeof(BITMAPINFO)};
bmpinfo.bmiHeader.biWidth = Width;
bmpinfo.bmiHeader.biHeight = Height;
bmpinfo.bmiHeader.biPlanes = 1;
bmpinfo.bmiHeader.biBitCount = 24;
bmpinfo.bmiHeader.biCompression = BI_RGB;
HBITMAP hBmp = CreateDIBSection(NULL, &bmpinfo, DIB_RGB_COLORS, (void**)&pBits, NULL, 0);
if(!hBmp)return 0;
ktGDIReleaser gdirelease((HGDIOBJ)hBmp);
HDC hDC = CreateCompatibleDC(hDesktopDC);
HBITMAP hOldBmp = (HBITMAP)SelectObject(hDC, hBmp);
BitBlt(hDC, 0, 0, Width, Height, hDesktopDC, 0, 0, SRCCOPY);
|
if (setjmp(png_jmpbuf(png_ptr))){
// エラーの時ここに来る。
SelectObject(hDC, hOldBmp);
DeleteDC(hDC);
return 0;
}
|
png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, Width, Height, 8, PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_BASE);
|
png_color_8 sig_bit;
sig_bit.red = 8;
sig_bit.green = 8;
sig_bit.blue = 8;
sig_bit.alpha = 0;
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
|
// PNGに書き込まれるコメント
png_text text_ptr[1];
text_ptr[0].key = "Description";
text_ptr[0].text = "ktcDIB::Save() Data";
text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
png_set_text(png_ptr, info_ptr, text_ptr, 1);
png_write_info(png_ptr, info_ptr);
|
png_write_info(png_ptr, info_ptr);
png_set_bgr(png_ptr);
|
#define Pixel(x, y) (pBits + Width * (Height - y - 1) * 3 + x * 3)
png_bytep *row_pointers;
row_pointers = (png_bytep *)malloc(sizeof(png_bytep *) * Height);
for (int k = 0; k < Height; k++)
row_pointers[k] = (png_bytep)Pixel(0, k);
png_write_image(png_ptr, row_pointers);
free(row_pointers);
png_write_end(png_ptr, info_ptr);
|