2bit パレット使用の画像を読み込んだ例。
#pragma once #include <cstdlib> #include <iostream> #include <bitset> #include <png.h> #pragma comment(lib,"libpng16d.lib") //エラーの時強制終了 void abort_(const char* c) { printf(c); abort(); }
//! @brief pngファイル読み込み関数 //! @param [in] file_name ファイル名 //! @param [out] width 画像幅(ピクセル) //! @param [out] height 画像高さ(ピクセル) //! @param [out] color_type RGBかRGBAか...等 //! @param [out] bit_depth チャンネルのビット数 //! @param [out] row_pointers 画像データへのポインタのポインタ //! @retval true 成功 //! @retval false 中断 bool read_png( const char* file_name, int* width, int* height, png_byte* color_type, png_byte* bit_depth, png_bytep** row_pointers ) { png_byte header[8]; // 8 is the maximum size that can be checked FILE* fp = fopen(file_name, "rb"); if (!fp) { abort_("[read_png_file] File could not be opened for reading"); } fread(header, 1, 8, fp); if (png_sig_cmp(header, 0, 8)) { abort_("[read_png_file] File is not recognized as a PNG file"); } png_structp png_ptr; png_infop info_ptr; /* initialize stuff */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) abort_("[read_png_file] png_create_read_struct failed"); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) abort_("[read_png_file] png_create_info_struct failed"); if (setjmp(png_jmpbuf(png_ptr))) abort_("[read_png_file] Error during init_io"); png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); ///////////////////////////////////////// // 画像情報の取得 *width = png_get_image_width(png_ptr, info_ptr); *height = png_get_image_height(png_ptr, info_ptr); *color_type = png_get_color_type(png_ptr, info_ptr); *bit_depth = png_get_bit_depth(png_ptr, info_ptr); // ///////////////////////////////////////// std::cout << "width : " << *width << std::endl; std::cout << "height: " << *height << std::endl; std::cout << "colortype: " << (int)*color_type << std::endl; std::cout << "bitdepth: " << (int)*bit_depth << std::endl;
///////////////////////////////////////// // グレイスケール パレットの時だけ処理する if ( *color_type == (PNG_COLOR_TYPE_GRAY | PNG_COLOR_TYPE_PALETTE)) { ///////////////////////////////////////// // パレット取得 png_colorp palette; int num; png_get_PLTE(png_ptr, info_ptr, &palette, &num); ///////////////////////////////////////// // パレット内容表示 std::cout << std::endl << "palette ( " << num << " )" << std::endl; for (int i = 0; i < num; i++) { std::cout << "[" << std::bitset<2>(i) << "] " << "(" << (int)palette[i].red << "," << (int)palette[i].green << "," << (int)palette[i].blue << ")" << std::endl; } }
///////////////////////////////////////// else { fclose(fp); return false; } int number_of_passes; number_of_passes = png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); /* read file */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[read_png_file] Error during read_image"); ///////////////////////////////////////// // 画像の読み込み *row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * *height); for (int y = 0; y < *height; y++) (*row_pointers)[y] = (png_byte*)malloc(png_get_rowbytes(png_ptr, info_ptr)); png_read_image(png_ptr, *row_pointers); // ///////////////////////////////////////// fclose(fp); return true; }
int main() { int width; int height; png_byte color_type; png_byte bit_depth; png_bytep* row_pointers; bool ret; //////////////////////////////// // 画像読み込み ret = read_png( R"(c:\test\test_2bit_palette_1x8.png)", &width, &height, &color_type, &bit_depth, &row_pointers ); // //////////////////////////////// if (ret == false) { return -1; }
//////////////////////////////// // 内容を表示 png_bytep yhead = row_pointers[0]; png_bytep xpix = yhead; std::cout << std::endl; std::cout << std::bitset<8>(xpix[0]); std::cout << std::bitset<8>(xpix[1]) << std::endl; // ///////////////////////////////////////////////
/////////////////////////////////////////////// // メモリの解放 for (size_t i = 0; i < (size_t)height; i++) { png_bytep yhead = row_pointers[i]; free(yhead); } free(row_pointers); // /////////////////////////////////////////////// int i; std::cin >> i; return 0; }
libpng 1bit / 4bit PNG_COLOR_TYPE_GRAY 出力
libpng PNG_COLOR_TYPE_PALETTEでパレットを使った出力
libpng パレット色(PNG_COLOR_TYPE_PALETTE)画像の読み込み
libpng 16bit PNG_COLOR_TYPE_GRAY 読み込み
画像は前のプログラムで出力したもの。
#pragma once #include <cstdlib> #include <iostream> #include <bitset> #include <png.h> #pragma comment(lib,"libpng16d.lib") //エラーの時強制終了 void abort_(const char* c) { printf(c); abort(); }
//! @brief pngファイル読み込み関数 //! @param [in] file_name ファイル名 //! @param [out] width 画像幅(ピクセル) //! @param [out] height 画像高さ(ピクセル) //! @param [out] color_type RGBかRGBAか...等 //! @param [out] bit_depth チャンネルのビット数 //! @param [out] row_pointers 画像データへのポインタのポインタ void read_png( const char* file_name, int* width, int* height, png_byte* color_type, png_byte* bit_depth, png_bytep** row_pointers ) { png_byte header[8]; // 8 is the maximum size that can be checked FILE* fp = fopen(file_name, "rb"); if (!fp) { abort_("[read_png_file] File could not be opened for reading"); } fread(header, 1, 8, fp); if (png_sig_cmp(header, 0, 8)) { abort_("[read_png_file] File is not recognized as a PNG file"); } png_structp png_ptr; png_infop info_ptr; /* initialize stuff */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) abort_("[read_png_file] png_create_read_struct failed"); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) abort_("[read_png_file] png_create_info_struct failed"); if (setjmp(png_jmpbuf(png_ptr))) abort_("[read_png_file] Error during init_io"); png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); ///////////////////////////////////////// // 画像情報の取得 *width = png_get_image_width(png_ptr, info_ptr); *height = png_get_image_height(png_ptr, info_ptr); *color_type = png_get_color_type(png_ptr, info_ptr); *bit_depth = png_get_bit_depth(png_ptr, info_ptr); // ///////////////////////////////////////// int number_of_passes; number_of_passes = png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); /* read file */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[read_png_file] Error during read_image"); ///////////////////////////////////////// // 画像の読み込み *row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * *height); for (int y = 0; y < *height; y++) (*row_pointers)[y] = (png_byte*)malloc(png_get_rowbytes(png_ptr, info_ptr)); png_read_image(png_ptr, *row_pointers); // ///////////////////////////////////////// fclose(fp); }
int main() { int width; int height; png_byte color_type; png_byte bit_depth; png_bytep* row_pointers; //////////////////////////////// // 画像読み込み read_png( R"(c:\test\test_bitdepth_1_notpalette_1x16px.png)", &width, &height, &color_type, &bit_depth, &row_pointers ); // //////////////////////////////// std::cout << "width : " << width << std::endl; std::cout << "height: " << height << std::endl; std::cout << "colortype: " << (int)color_type << std::endl; std::cout << "bitdepth: " << (int)bit_depth << std::endl; //////////////////////////////// //今回は1ビットグレイスケール画像だけを対象にする if ((color_type != PNG_COLOR_TYPE_GRAY) || (bit_depth != 1) ) { return -1; } // ////////////////////////////////
//////////////////////////////// // 内容を表示 png_bytep yhead = row_pointers[0]; png_bytep xpix = yhead; std::cout << "[0]" << std::bitset<8>(xpix[0]) << std::endl; std::cout << "[1]" << std::bitset<8>(xpix[1]) << std::endl; // ///////////////////////////////////////////////
/////////////////////////////////////////////// // メモリの解放 for (size_t i = 0; i < (size_t)height; i++) { png_bytep yhead = row_pointers[i]; free(yhead); } free(row_pointers); // /////////////////////////////////////////////// int i; std::cin >> i; }
libpng 1bit / 4bit PNG_COLOR_TYPE_GRAY 出力
libpng PNG_COLOR_TYPE_PALETTEでパレットを使った出力
libpng パレット色(PNG_COLOR_TYPE_PALETTE)画像の読み込み
libpng 16bit PNG_COLOR_TYPE_GRAY 読み込み
GrayScaleの値をパレット色に置き換える。

Color Typeを PNG_COLOR_TYPE_GRAY | PNG_COLOR_TYPE_PALETTE
あとは png_set_PLTE でパレットを設定する。
それ以外はRGBやただのグレースケールの時と変わらない。
#include <cstdlib> #include <png.h> #pragma comment(lib,"libpng16d.lib") //エラーの時強制終了 void abort_(const char* c) { printf(c); abort(); } int main() { int width; int height; png_byte color_type = PNG_COLOR_TYPE_GRAY | PNG_COLOR_TYPE_PALETTE; png_byte bit_depth = 1; png_bytep* row_pointers;
//////////////////////////////// // 画像作成 height = 1; width = 8; row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height); row_pointers[0] = (png_byte*)malloc(1); png_byte* xhead; xhead = row_pointers[0]; xhead[0] = 0b01010111; // ////////////////////////////////
const char* file_name = R"(c:\test\test_palette.png)"; /* create file */ FILE* fp = fopen(file_name, "wb"); if (!fp) abort_("[write_png_file] File could not be opened for writing"); png_structp png_ptr; /* initialize stuff */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) abort_("[write_png_file] png_create_write_struct failed"); png_infop info_ptr; info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) abort_("[write_png_file] png_create_info_struct failed"); if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during init_io");
//////////////////// ////// パレット png_colorp palette = nullptr; palette = (png_colorp)png_malloc(png_ptr, sizeof(png_color) * 2); palette[0].red = 255; palette[0].green = 0; palette[0].blue = 0; palette[1].red = 0; palette[1].green = 255; palette[1].blue = 0; png_set_PLTE(png_ptr, info_ptr, palette, 2); ////// ////////////////////
png_init_io(png_ptr, fp); ///////////////////////////////////// //ヘッダの設定 if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during writing header"); png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); // ///////////////////////////////////// ///////////////////////////////////// // 画像のファイル出力 if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during writing bytes"); png_write_image(png_ptr, row_pointers); // end write if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during end of write"); png_write_end(png_ptr, NULL); // ///////////////////////////////////// fclose(fp); /////////////////////////////////////////////// // メモリの解放 for (size_t i = 0; i < (size_t)height; i++) { png_bytep yhead = row_pointers[i]; free(yhead); } free(row_pointers); // /////////////////////////////////////////////// }
libpng 1bit / 4bit PNG_COLOR_TYPE_GRAY 出力
libpng PNG_COLOR_TYPE_PALETTEでパレットを使った出力
libpng パレット色(PNG_COLOR_TYPE_PALETTE)画像の読み込み
libpng 16bit PNG_COLOR_TYPE_GRAY 読み込み
libpngにおいて、RGBやRGBA以外、特にbit depthが8bit未満の時どんな風に扱うのかの確認。
以下はPNG_COLOR_TYPE_GRAY のbit_depth == 1 についてファイル出力を行う場合。GIMPで開いて対応を確認すると、各ビットが下図のように対応している。
※ write_pngは前回作成した関数。
http://www.libpng.org/pub/png/libpng-1.2.5-manual.html
PNG_COLOR_TYPE_GRAYに対応するbit depthは
(bit depths 1, 2, 4, 8, 16)
#include <iostream> #include <png.h> #pragma comment(lib,"libpng16d.lib") //エラーの時強制終了 void abort_(const char* c) { printf(c); abort(); }
//! @brief pngファイル書き込み関数 //! @param [in] file_name ファイル名 //! @param [in] width 画像幅(ピクセル) //! @param [in] height 画像高さ(ピクセル) //! @param [in] color_type RGBかRGBAか...等 //! @param [in] bit_depth チャンネルのビット数 //! @param [in] row_pointers 画像データへのポインタ void write_png( const char* file_name, const int width, const int height, const int color_type, const int bit_depth, const png_bytepp row_pointers ) { /* create file */ FILE* fp = fopen(file_name, "wb"); if (!fp) abort_("[write_png_file] File could not be opened for writing"); png_structp png_ptr; /* initialize stuff */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) abort_("[write_png_file] png_create_write_struct failed"); png_infop info_ptr; info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) abort_("[write_png_file] png_create_info_struct failed"); if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during init_io"); png_init_io(png_ptr, fp); ///////////////////////////////////// //ヘッダの設定 if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during writing header"); png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); // ///////////////////////////////////// ///////////////////////////////////// // 画像のファイル出力 if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during writing bytes"); png_write_image(png_ptr, row_pointers); // end write if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during end of write"); png_write_end(png_ptr, NULL); // ///////////////////////////////////// fclose(fp); }
int main() { int width; int height; png_byte color_type = PNG_COLOR_TYPE_GRAY; png_byte bit_depth = 4; png_bytep* row_pointers; //////////////////////////////// // 画像作成 height = 1; width = 5; row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height); row_pointers[0] = (png_byte*)malloc(3); png_byte* xhead; xhead = row_pointers[0]; xhead[0] = 0xFC; xhead[1] = 0xA7; xhead[2] = 0x3F; // //////////////////////////////// //////////////////////////////// // 画像書き込み write_png( R"(c:\test\test_bitdepth.png)", width, height, color_type, bit_depth, row_pointers ); // //////////////////////////////// /////////////////////////////////////////////// // メモリの解放 for (size_t i = 0; i < (size_t)height; i++) { png_bytep yhead = row_pointers[i]; free(yhead); } free(row_pointers); // /////////////////////////////////////////////// std::cout << "fin" << std::endl; }
libpng 1bit / 4bit PNG_COLOR_TYPE_GRAY 出力
libpng PNG_COLOR_TYPE_PALETTEでパレットを使った出力
libpng パレット色(PNG_COLOR_TYPE_PALETTE)画像の読み込み
libpng 16bit PNG_COLOR_TYPE_GRAY 読み込み
//参考元: //http://zarb.org/~gc/html/libpng.html #include <iostream> #include <png.h> #pragma comment(lib,"libpng16.lib") //エラーの時強制終了 void abort_(const char* c) { printf(c); abort(); }
//! @brief pngファイル書き込み関数 //! @param [in] file_name ファイル名 //! @param [in] width 画像幅(ピクセル) //! @param [in] height 画像高さ(ピクセル) //! @param [in] color_type RGBかRGBAか...等 //! @param [in] bit_depth チャンネルのビット数 //! @param [in] row_pointers 画像データへのポインタ void write_png( const char* file_name, const int width, const int height, const int color_type, const int bit_depth, const png_bytepp row_pointers ) { /* create file */ FILE* fp = fopen(file_name, "wb"); if (!fp) abort_("[write_png_file] File could not be opened for writing"); png_structp png_ptr; /* initialize stuff */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) abort_("[write_png_file] png_create_write_struct failed"); png_infop info_ptr; info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) abort_("[write_png_file] png_create_info_struct failed"); if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during init_io"); png_init_io(png_ptr, fp);
///////////////////////////////////// //ヘッダの設定 if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during writing header"); png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); // /////////////////////////////////////
///////////////////////////////////// // 画像のファイル出力 if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during writing bytes"); png_write_image(png_ptr, row_pointers); // end write if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during end of write"); png_write_end(png_ptr, NULL); // /////////////////////////////////////
fclose(fp); }
int main() { int width; int height; png_byte color_type = PNG_COLOR_TYPE_RGB_ALPHA; //RGBA png_byte bit_depth = 8; // 1 pixel == 8bit * 4 png_bytep* row_pointers;
//////////////////////////////// // 画像作成 height = 256; width = 128; row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height); for (int y = 0; y < height; y++) { row_pointers[y] = (png_byte*)malloc(width * 4); png_byte* xhead = row_pointers[y]; for (int x = 0; x < width; x++) { png_byte r = y; png_byte g = x*2; png_byte b = 128; png_byte a = 128 + (255 - r) / 2; png_byte* px = xhead + x * 4; px[0] = r; px[1] = g; px[2] = b; px[3] = a; } } // ////////////////////////////////
//////////////////////////////// // 画像書き込み write_png( R"(c:\test\test.png)", width, height, color_type, bit_depth, row_pointers ); // ////////////////////////////////
/////////////////////////////////////////////// // メモリの解放 for (size_t i = 0; i < (size_t)height; i++) { png_bytep yhead = row_pointers[i]; free(yhead); } free(row_pointers); // ///////////////////////////////////////////////
std::cout << "fin" << std::endl; }
libpng 1bit / 4bit PNG_COLOR_TYPE_GRAY 出力
libpng PNG_COLOR_TYPE_PALETTEでパレットを使った出力
libpng パレット色(PNG_COLOR_TYPE_PALETTE)画像の読み込み
libpng 16bit PNG_COLOR_TYPE_GRAY 読み込み
//参考元: //http://zarb.org/~gc/html/libpng.html #include <iostream> #include <png.h> #pragma comment(lib,"libpng16.lib") //エラーの時強制終了 void abort_(const char* c) { printf(c); abort(); }
//! @brief pngファイル読み込み関数 //! @param [in] file_name ファイル名 //! @param [out] width 画像幅(ピクセル) //! @param [out] height 画像高さ(ピクセル) //! @param [out] color_type RGBかRGBAか...等 //! @param [out] bit_depth チャンネルのビット数 //! @param [out] row_pointers 画像データへのポインタのポインタ void read_png( const char* file_name, int* width, int* height, png_byte* color_type, png_byte* bit_depth, png_bytep** row_pointers ) { png_byte header[8]; // 8 is the maximum size that can be checked FILE *fp = fopen(file_name, "rb"); if (!fp) { abort_("[read_png_file] File could not be opened for reading"); } fread(header, 1, 8, fp); if (png_sig_cmp(header, 0, 8)) { abort_("[read_png_file] File is not recognized as a PNG file"); } png_structp png_ptr; png_infop info_ptr; /* initialize stuff */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) abort_("[read_png_file] png_create_read_struct failed"); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) abort_("[read_png_file] png_create_info_struct failed"); if (setjmp(png_jmpbuf(png_ptr))) abort_("[read_png_file] Error during init_io"); png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr);
///////////////////////////////////////// // 画像情報の取得 *width = png_get_image_width(png_ptr, info_ptr); *height = png_get_image_height(png_ptr, info_ptr); *color_type = png_get_color_type(png_ptr, info_ptr); *bit_depth = png_get_bit_depth(png_ptr, info_ptr); // /////////////////////////////////////////
int number_of_passes; number_of_passes = png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); /* read file */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[read_png_file] Error during read_image");
///////////////////////////////////////// // 画像の読み込み *row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * *height); for (int y=0; y < *height; y++) (*row_pointers)[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr)); png_read_image(png_ptr, *row_pointers); // /////////////////////////////////////////
fclose(fp); }
int main() { int width; int height; png_byte color_type; png_byte bit_depth; png_bytep* row_pointers; //////////////////////////////// // 画像読み込み read_png( R"(c:\test\test.png)", &width, &height, &color_type, &bit_depth, &row_pointers ); // //////////////////////////////// std::cout << "width : " << width << std::endl; std::cout << "height: " << height << std::endl; std::cout << "colortype: " << (int)color_type << std::endl; std::cout << "bitdepth: " << (int)bit_depth << std::endl; //////////////////////////////// //1ピクセルのバイト数を算出 //RGBかRGBAだけ出力 int pixelsize; switch (color_type){ case PNG_COLOR_TYPE_RGB: pixelsize = bit_depth / 8 * 3; break; case PNG_COLOR_TYPE_RGB_ALPHA: pixelsize = bit_depth / 8 * 4; break; default: std::cout << "RGB/RGBA only" << std::endl; } // ////////////////////////////////
/////////////////////////////////////////////// // PPM形式に変換して出力 FILE* fp = fopen(R"(C:\test\out.ppm)", "wb"); fprintf(fp, "P3\n%d %d\n%d\n", width, height, 255); size_t k = 0; for (size_t i = 0; i < (size_t)height; i++) { png_bytep yhead = row_pointers[i]; for (size_t j = 0; j < (size_t)width; j++) { png_bytep xpix = yhead + pixelsize * j; fprintf(fp, "%d %d %d ", xpix[0], xpix[1], xpix[2]); k++; } fprintf(fp, "\n"); } fclose(fp); // ///////////////////////////////////////////////
/////////////////////////////////////////////// // メモリの解放 for (size_t i = 0; i < (size_t)height; i++) { png_bytep yhead = row_pointers[i]; free(yhead); } free(row_pointers); // /////////////////////////////////////////////// std::cout << "fin" << std::endl; int i; std::cin >> i; }


libpng 1bit / 4bit PNG_COLOR_TYPE_GRAY 出力
libpng PNG_COLOR_TYPE_PALETTEでパレットを使った出力
libpng パレット色(PNG_COLOR_TYPE_PALETTE)画像の読み込み
libpng 16bit PNG_COLOR_TYPE_GRAY 読み込み
まず、以下へ行き、「Source code: 」から.zipをダウンロードする
http://www.libpng.org/pub/png/libpng.html
次にzlibをダウンロードする。libpng1637/RADMEには以下のように書かれている。
lpng1637\README
You should use zlib 1.0.4 or later to run this, but it MAY work with
versions as old as zlib 0.95.
例えば以下のようにディレクトリを構成する

以下のように設定し、ConfigureしてGenerateしてOpen Projectする。
VC++からDebug x64 及び Release x64について、ALL_BUILDする。
ALL_BUILDが終わったらINSTALLする。
完了すると、zlib-installディレクトリに必要ファイルが出力されている
以下のように設定し、ConfigureしてGenerateしてOpen Projectする。
上記zlibと同じように、Debug x64 と Release x64 について、All_BUILD して INSTALL する
完了すると、libpng-installディレクトリに必要ファイルが出力されている
まだlibpngやってなかったことに自分でびっくりしている。
次回はライブラリを使うことを考える。
libpng 1bit / 4bit PNG_COLOR_TYPE_GRAY 出力
libpng PNG_COLOR_TYPE_PALETTEでパレットを使った出力
libpng パレット色(PNG_COLOR_TYPE_PALETTE)画像の読み込み
libpng 16bit PNG_COLOR_TYPE_GRAY 読み込み
C言語のsetjmpとlongjmpについて。
libpngのサンプルでsetjmpが出てきてびっくりしたので挙動の確認をしておきたい。
setjmp /longjmp はセットで使う。
1.setjmpを一回呼び出すと、必ず0を返して戻ってくる。
2.その後、longjmpを呼び出すと、先ほどsetjmpが呼ばれた文まで戻り、再びsetjmpが呼ばれる。
3.その時のsetjmpの戻り値は、先に呼び出したlongjmpの第二引数となる
これだけだとgotoと似たようなものに思えるが、setjmpに対するlongjmpの呼び出しは、別の関数の中でもかまわない。関数を飛び越えて戻ってくる。
#include <csetjmp>
std::jmp_buf jmp_bf; int main() { int a = 3; int b = 0; if (setjmp(jmp_bf) == 0) { if (b == 0) { longjmp(jmp_bf, 1); } int c = a / b; printf("%d / %d = %d", a, b, c); } else { printf("0 divide error.\n"); } }
C言語には例外(try...catch...)がない。この、「関数を飛び越えて戻ってくる」という特性を生かして、C言語で例外処理に近いことができる。
つまり、以下のC++コードに近いことができる。
int main() { int a = 3; int b = 0; try{ int c = a / b; printf("%d / %d = %d", a, b, c); } catch(...) { std::cout << "0 divide error"; } std::cout << "Hello World!\n"; }
#include <iostream> #include <csetjmp> std::jmp_buf jmp_bf;
int divide(int a, int b) { if (b == 0) { longjmp(jmp_bf, 1);//mainのsetjmpまで飛ぶ } return a / b; }
int main() { int a = 3; int b = 0;
//初回は0
//longjmp後は1
if (setjmp(jmp_bf) == 0) { int c = divide(a,b); printf("%d / %d = %d", a, b, c); } else { printf("0 divide error.\n"); } }
Visual Studioのオフラインインストーラを作成する方法。
https://visualstudio.microsoft.com/ja/downloads/?rr=https%3A%2F%2Fqiita.com%2F
例えば以下のようになる。以下では加えて--lang ja-JPを指定し、言語を日本語のみに絞っている。VS丸ごと全部のイメージは非常に大きいので絞れるところは絞ったほうがいい
なお--langなどの「--」はハイフン二本。
その他にも、--addオプションでどのコンポーネントをダウンロードするかを指定できる。以下はVC++に必要なものを入れた・・・つもりなのだが実際に実行してみると結局オンラインダウンロードが必要になってしまった。自分が必要なものだけを確実に抜き出すのは結構難しいようだ。
※改行は入れない。全てスペース区切り。