スポンサーリンク

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

ソースコード

//参考元:
//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を試す(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

1 件のコメント

  • お礼

     libpng1.6.37のビルドが正しく行われたか(libファイルがちゃんと作れたのか)、コピペで動作チェックが直ぐ出来る様なソースを探しておりましたところ貴サイトを拝見。すぐ当方の環境(Win10,C++Builder10.4(1年間無料),firemonkey)に貼付けビルド。スムーズにtest.pngが作成されました。お蔭さまで少しホットしたところです。ありがとうございました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

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


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