C++の応用 - 画像

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動

概要



libpngライブラリ

ライセンス

libpngライブラリは、libpngライセンス(PNG Reference Library License version 2)として提供されている。

このライセンスは、以下に示すような特徴がある。

  • ライブラリの出所を偽ってはならず、開発者がlibpngライブラリを開発したと主張してはならない。
  • libpngライブラリを製品に使用する場合、製品のドキュメントにその旨を明記することが望まれるが、必須ではない。
  • この著作権表示は、いかなるソースまたは変更されたソースの配布物からも削除または変更することはできない。


インストール

パッケージ管理システムからインストールする場合
# RHEL
sudo dnf install libpng-devel 

# SUSE
sudo zypper install libpng16-devel 


ソースコードからインストールする場合

libpngライブラリのビルドに必要なライブラリをインストールする。

# RHEL
sudo dnf install gawk make gcc gcc-c++ zlib-devel \
                 cmake  # CMakeを使用する場合

# SUSE
sudo zypper install gawk make gcc gcc-c++ zlib-devel \
                    cmake  # CMakeを使用する場合


libpngライブラリのGithubにアクセスして、ソースコードをダウンロードする。
ダウンロードしたファイルを解凍する。

tar xf libpng-<バージョン>
cd libpng-<バージョン>


libpngライブラリをビルドおよびインストールする。

mkdir build && cd build

# Configureスクリプトを使用する場合
../configure --prefix=<libpngライブラリのインストールディレクトリ>
make -j $(nproc)
make install

# CMakeを使用する場合
cmake -DCMAKE_INSTALL_PREFIX=<libpngライブラリのインストールディレクトリ> -DCMAKE_BUILD_TYPE=Release 
      -DPNG_TOOLS=ON \  # libpngライブラリのツール群をインストールする場合
      ..
make -j $(nproc)
make install


使用例

以下の例では、libpngライブラリを使用してPPM形式の画像をPNG形式に変換している。
PPM形式の画像がシンプルなP6形式 (バイナリ形式) であり、RGBカラーを持つと仮定している。

 #include <iostream>
 #include <fstream>
 #include <vector>
 #include <stdexcept>
 #include <png.h>
 
 
 // PPM画像の読み込み
 std::vector<unsigned char> readPPM(const std::string& filename, int& width, int& height)
 {
    std::ifstream file(filename, std::ios::binary);
    if (!file) {
       throw std::runtime_error("File opening failed: " + filename);
    }
 
    std::string line;
    std::getline(file, line); // PPMタイプを読み込む
    if (line.substr(0, 2) != "P6") {
       throw std::runtime_error("Invalid PPM format (must be 'P6')");
    }
 
    // コメントをスキップ
    do {
        std::getline(file, line);
    } while (line[0] == '#');
 
    std::stringstream ss(line);
    ss >> width >> height;
 
    file.ignore(256, '\n'); // 最大値を読み飛ばす
 
    std::vector<unsigned char> img(3 * width * height);
    file.read(reinterpret_cast<char*>(img.data()), img.size());
 
    return img;
 }
 
 // PNGファイルの作成
 void writePNG(const std::string &filename, const std::vector<unsigned char> &img, int width, int height)
 {
    FILE* fp = fopen(filename.c_str(), "wb");
    if (!fp) {
       throw std::runtime_error("File opening failed: " + filename);
    }
 
    png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
    if (!png_ptr) {
       fclose(fp);
       throw std::runtime_error("Failed to create PNG write structure");
    }

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
       png_destroy_write_struct(&png_ptr, nullptr);
       fclose(fp);
       throw std::runtime_error("Failed to create PNG info structure");
    }
 
    if (setjmp(png_jmpbuf(png_ptr))) {
       png_destroy_write_struct(&png_ptr, &info_ptr);
       fclose(fp);
       throw std::runtime_error("Error during PNG creation");
    }
 
    png_init_io(png_ptr, fp);
 
    png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
 
    png_write_info(png_ptr, info_ptr);
 
    for (int y = 0; y < height; y++) {
       png_write_row(png_ptr, img.data() + y * width * 3);
    }
 
    png_write_end(png_ptr, nullptr);
 
    fclose(fp);
    png_destroy_write_struct(&png_ptr, &info_ptr);
 }
 
 int main()
 {
    try {
       const std::string ppmFilename = "input.ppm";
       const std::string pngFilename = "output.png";
 
       int width  = 0,
           height = 0;
 
       // PPM形式の画像を読み込む
       auto img = readPPM(ppmFilename, width, height);
 
       // PNG形式の画像を作成する
       writePNG(pngFilename, img, width, height);
    }
    catch (const std::exception& e) {
       std::cerr << "Error: " << e.what() << std::endl;
       return -1;
    }
 
    return 0;
 }


libpngライブラリをアプリケーションで使用する例については、example.cファイルおよびpngtest.cファイルを参照する。
libpngライブラリの使用方法や制限事項については、png.hファイルを参照する。
zlib (libpngが使用する圧縮ライブラリ) の使用に関する説明とzlibの制限事項については、zlib.hファイルを参照する。