スポンサーリンク

libpng 1bit / 4bit PNG_COLOR_TYPE_GRAY 出力

libpngにおいて、RGBやRGBA以外、特にbit depthが8bit未満の時どんな風に扱うのかの確認。

以下はPNG_COLOR_TYPE_GRAY のbit_depth == 1 についてファイル出力を行う場合。GIMPで開いて対応を確認すると、各ビットが下図のように対応している。

※ write_pngは前回作成した関数。

例1 bit depth == 1 の場合

例2 bit depth == 4 の場合

PNG_COLOR_TYPE_GRAY対応のBit depth

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を試す(CMakeビルド)

libpngを試す(ファイル読み込み)

libpngを試す(ファイル書き込み)

libpng 1bit / 4bit PNG_COLOR_TYPE_GRAY 出力

libpng PNG_COLOR_TYPE_PALETTEでパレットを使った出力

libpng 1bit Grayscale画像の読み込み

libpng パレット色(PNG_COLOR_TYPE_PALETTE)画像の読み込み

libpng 16bit PNG_COLOR_TYPE_GRAY 読み込み

libpng 16bit PNG_COLOR_TYPE_GRAY 出力

setjmp / longjmp

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: