スポンサーリンク

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 [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;

}

実行結果

https://pixabay.com/ja/illustrations/%E7%8C%AB-%E5%AD%90%E7%8C%AB-%E5%8B%95%E7%89%A9-%E3%83%9A%E3%83%83%E3%83%88-1348502/

元ファイル
ppmファイル出力結果

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: