スポンサーリンク

libpng 16bit PNG_COLOR_TYPE_GRAY 出力

16bit Grayscale画像の場合、以下のコードのように、2byte値の前後を交換して与えなければいけない。

ソースコード

#include <cstdlib>
#include<algorithm>

#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_byte bit_depth = 16;// 2バイト

  png_bytep* row_pointers;
  ////////////////////////////////
  // 画像作成
  height = 1;
  width = 4;
  row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
  row_pointers[0] = (png_byte*)malloc(4*2);
  png_byte* xhead;
  xhead = row_pointers[0];
  unsigned short* p0 = (unsigned short*)&xhead[0];// 1byte置きに画素を配置する
  unsigned short* p1 = (unsigned short*)&xhead[2];
  unsigned short* p2 = (unsigned short*)&xhead[4];
  unsigned short* p3 = (unsigned short*)&xhead[6];

  unsigned short v;

  *p0 = 0;

  v = USHRT_MAX / 4;// 画素値を設定
  std::swap( ((unsigned char*)(&v))[0], ((unsigned char*)(&v))[1]);// 2byte画素値の前後を入れ替える
  *p1 = v;

  v = USHRT_MAX/2;// 画素値を設定
  std::swap(((unsigned char*)(&v))[0], ((unsigned char*)(&v))[1]);// 2byte画素値の前後を入れ替える
  *p2 = v;

  v = USHRT_MAX;// 画素値を設定
  std::swap(((unsigned char*)(&v))[0], ((unsigned char*)(&v))[1]);// 2byte画素値の前後を入れ替える
  *p3 = v;

  //
  ////////////////////////////////
  const char* file_name = R"(c:\test\test_16bit_1x4.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_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を試す(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: