こちらでは Mac に libpng をインストールする手順と libpng を用いたプログラムの例を紹介します。
試したOSは下記の通りです。他の環境では試せていませんのでご了承ください。
- macOS HighSierra( バージョン10.13.4)
RGB+αの画像形式にも対応しました
ダウンロードされるフォルダ違うなどの違いがありますが、LINUX 環境でも手順は参考になると思います。
Contents
libpng とは
libpng は PNG 画像ファイルを扱うためのライブラリです。
この libpng を利用することで、C言語などのプログラムから簡単に PNG 画像を読み込んだり、PNG 画像を作成したりできるようになります。
libpng のインストール
それでは libpng のインストール方法について解説していきます。
このインストールの基本的な流れは下記になります。
- ダウンロード
- 設定
- ライブラリ生成
- インストール
- インストールの確認
スポンサーリンク
libpng のダウンロード
まず libpng をダウンロードします。
libpng のダウンロードは下記 URL から行うことができます。
https://sourceforge.net/projects/libpng/files/
最新バージョンは下図の緑色のボタンからダウンロードできます。
2018/9/7 だと 1.6.35 が最新のようでした。
続いてターミナルでダウンロードしたファイルがあるフォルダにアクセスします。ターミナルアプリは「アプリケーション」→「ユーティリティ」にあります。
私がダウンロードしたファイルをダウンロードフォルダに保存しましたので下記コマンドでフォルダにアクセスしました。
cd /Users/[私のユーザ名]/Downloads/
続いてダウンロードした .tar.gz を下記コマンドにより展開します。「libpng-1.6.35.tar.gz」の部分はダウンロードしてきたファイル名に合わせて変更してください
tar xvzf libpng-1.6.35.tar.gz
フォルダが作成され、その中に様々なファイルが展開されるはずです。
私の場合は「libpng-1.6.35」というフォルダが作成されました。展開が完了したら、その作成したフォルダに cd
コマンドで移動しましょう。
libpng の設定
続いてそのフォルダで下記コマンドを実行します。これによりあなたの PC 環境に合わせて libpng の設定が行われます。
./configure
このコマンド実行するとメッセージが表示され、1分くらいで処理が完了すると思います。
最後の方のメッセージは下記のような感じでした。良ければご参考に。
checking for size_t... yes checking whether struct tm is in sys/time.h or time.h... time.h checking for C/C++ restrict keyword... __restrict checking for working strtod... yes checking for memset... yes checking for pow... yes checking for clock_gettime... yes checking for zlibVersion in -lz... yes checking for feenableexcept in -lm... no checking for feenableexcept... no checking if using Solaris linker... no checking if libraries can be versioned... no configure: WARNING: *** You have not enabled versioned symbols. configure: pkgconfig directory is ${libdir}/pkgconfig configure: Extra options for compiler: checking that generated files are newer than configure... done configure: creating ./config.status config.status: creating Makefile config.status: creating libpng.pc config.status: creating libpng-config config.status: creating config.h config.status: executing depfiles commands config.status: executing libtool commands
libpng ライブラリの生成
続いて同じフォルダ内で下記 make
コマンドを実行します。これにより libpng ライブラリが生成されます。
make
こちらも1分ほどで処理完了します。最後の方のメッセージはこんな感じ。
mv -f $depbase.Tpo $depbase.Po /bin/sh ./libtool --tag=CC --mode=link gcc -g -O2 -o pngimage contrib/libtests/pngimage.o libpng16.la -lz libtool: link: gcc -g -O2 -o .libs/pngimage contrib/libtests/pngimage.o ./.libs/libpng16.dylib -lz depbase=`echo contrib/tools/pngcp.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\ gcc -DHAVE_CONFIG_H -I. -g -O2 -MT contrib/tools/pngcp.o -MD -MP -MF $depbase.Tpo -c -o contrib/tools/pngcp.o contrib/tools/pngcp.c &&\ mv -f $depbase.Tpo $depbase.Po /bin/sh ./libtool --tag=CC --mode=link gcc -g -O2 -o pngcp contrib/tools/pngcp.o libpng16.la -lz libtool: link: gcc -g -O2 -o .libs/pngcp contrib/tools/pngcp.o ./.libs/libpng16.dylib -lz depbase=`echo contrib/libtests/timepng.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\ gcc -DHAVE_CONFIG_H -I. -g -O2 -MT contrib/libtests/timepng.o -MD -MP -MF $depbase.Tpo -c -o contrib/libtests/timepng.o contrib/libtests/timepng.c &&\ mv -f $depbase.Tpo $depbase.Po /bin/sh ./libtool --tag=CC --mode=link gcc -g -O2 -o timepng contrib/libtests/timepng.o libpng16.la -lz libtool: link: gcc -g -O2 -o .libs/timepng contrib/libtests/timepng.o ./.libs/libpng16.dylib -lz
スポンサーリンク
libpng のインストール
次に libpng をインストールします。次のコマンドによりインストールが行われるはずです。
sudo make install
コマンドを実行するとパスワードが求められますので、管理者のパスワード(Macのパスワード)を入力してください。
管理者権限でないとファイルの編集や追加削除の権限がなくてコマンド実行しても失敗します。なので、管理者権限でインストールが行えるように、コマンドの最初に sudo
を付けています。
インストールはすぐ処理が完了すると思います。最後の方のメッセージを念のため載せておきます。
./install-sh -c -d '/usr/local/share/man/man3' /usr/bin/install -c -m 644 libpng.3 libpngpf.3 '/usr/local/share/man/man3' ./install-sh -c -d '/usr/local/share/man/man5' /usr/bin/install -c -m 644 png.5 '/usr/local/share/man/man5' ./install-sh -c -d '/usr/local/include/libpng16' /usr/bin/install -c -m 644 pnglibconf.h '/usr/local/include/libpng16' ./install-sh -c -d '/usr/local/lib/pkgconfig' /usr/bin/install -c -m 644 libpng16.pc '/usr/local/lib/pkgconfig' ./install-sh -c -d '/usr/local/include/libpng16' /usr/bin/install -c -m 644 png.h pngconf.h '/usr/local/include/libpng16' /Applications/Xcode.app/Contents/Developer/usr/bin/make install-data-hook + cd /usr/local/include + for f in pnglibconf.h png.h pngconf.h + rm -f pnglibconf.h + ln -s libpng16/pnglibconf.h pnglibconf.h + for f in pnglibconf.h png.h pngconf.h + rm -f png.h + ln -s libpng16/png.h png.h + for f in pnglibconf.h png.h pngconf.h + rm -f pngconf.h + ln -s libpng16/pngconf.h pngconf.h + cd /usr/local/lib/pkgconfig + rm -f libpng.pc + ln -s libpng16.pc libpng.pc
インストールの確認
最後にインストールされたことを確認しておきましょう。
今まで作成したC言語のプログラムファイルをコンパイルしてやるときに、最後に -lpng
をつけてからコンパイルしてみてください。下記のような感じです。
gcc japanese.c -o japanese.exe -lpng
-lpng
を付けることで libpng へのリンクが行われます。これにより自分のプログラムで PNG 関連の様々な関数が使用可能になります。
エラーが表示されずコンパイルが完了すれば、libpng のインストールに成功です。
インストールがうまくできていなければ下記のようなメッセージが表示されますので再度手順を確認してみてください。
ld: library not found for -lpng clang: error: linker command failed with exit code 1 (use -v to see invocation)
libpng を使用したPNGファイル読み込み・書き込み関数の作成
続いて、インストールした libpng を用いて PNG ファイルを読み込み・書き込みを行う関数の例を紹介していきたいと思います。
lipng が提供する関数の使い方を詳細に知りたい方はlibpngが提供する関数で紹介している libpng のマニュアルを読んで見てください。
スポンサーリンク
ヘッダーファイル
まずは libpng に関連するヘッダーをインクルードしたり、必要な構造体の定義、PNG ファイルを読み込み・書き込みする関数の定義を行うヘッダーファイルを用意します。
下記がそのヘッダーファイルの例になります。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "png.h"
typedef struct{
unsigned char *data;
unsigned int width;
unsigned int height;
unsigned int ch;
} BITMAPDATA_t;
int pngFileReadDecode(BITMAPDATA_t *, const char*);
int pngFileEncodeWrite(BITMAPDATA_t *, const char*);
int freeBitmapData(BITMAPDATA_t *);
#define SIGNATURE_NUM 8
ポイントを説明していきます。
png.h
のインクルード
libpng が提供する関数の宣言や定数等の定義は png.h
で行われています。
ですので、libpng を利用する際には、この png.h
のインクルードを行う必要があります。
#include "png.h"
BITMAP 形式データ構造体の定義
また、下記では BITMAP 形式データの情報格納用構造体 BITMAPDATA_t
を定義しています。
typedef struct{
unsigned char *data;
unsigned int width;
unsigned int height;
unsigned int ch;
} BITMAPDATA_t;
それぞれのメンバの説明は下記のようになります。
data
:PNG をデコードした BITMAP 形式画像データの先頭アドレスwidth
:画像の横幅height
:画像の高さch
:画像の色数(RGB+αの時は4
、RGBの時は3
、グレーの時は1
)
BITMAP 形式画像データって何?という方は下記ページで説明していますので是非参考にしてください。
画像データの構造・画素・ビットマップデータについて解説上のページでも解説しているように data
のポインタの先は下図のように各ピクセルの RGB 順にデータが並んでいます。
RGB+α形式の場合は、各ピクセルがRGBα順にデータが並びます
ソースファイル
次は実際に libpng が提供している関数を利用して PNG ファイルを読み込んだり、PNG ファイルとして保存したりする関数を作成していきます。
#include "myPng.h"
int pngFileReadDecode(BITMAPDATA_t *bitmapData, const char* filename){
FILE *fi;
int j;
unsigned int width, height;
unsigned int readSize;
png_structp png;
png_infop info;
png_bytepp datap;
png_byte type;
png_byte signature[8];
fi = fopen(filename, "rb");
if(fi == NULL){
printf("%sは開けません\n", filename);
return -1;
}
readSize = fread(signature, 1, SIGNATURE_NUM, fi);
if(png_sig_cmp(signature, 0, SIGNATURE_NUM)){
printf("png_sig_cmp error!\n");
fclose(fi);
return -1;
}
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(png == NULL){
printf("png_create_read_struct error!\n");
fclose(fi);
return -1;
}
info = png_create_info_struct(png);
if(info == NULL){
printf("png_crete_info_struct error!\n");
png_destroy_read_struct(&png, NULL, NULL);
fclose(fi);
return -1;
}
png_init_io(png, fi);
png_set_sig_bytes(png, readSize);
png_read_png(png, info, PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_16, NULL);
width = png_get_image_width(png, info);
height = png_get_image_height(png, info);
datap = png_get_rows(png, info);
type = png_get_color_type(png, info);
/* とりあえずRGB or RGBAだけ対応 */
if(type != PNG_COLOR_TYPE_RGB && type != PNG_COLOR_TYPE_RGB_ALPHA){
printf("color type is not RGB or RGBA\n");
png_destroy_read_struct(&png, &info, NULL);
fclose(fi);
return -1;
}
bitmapData->width = width;
bitmapData->height = height;
if(type == PNG_COLOR_TYPE_RGB) {
bitmapData->ch = 3;
} else if(type == PNG_COLOR_TYPE_RGBA) {
bitmapData->ch = 4;
}
printf("width = %d, height = %d, ch = %d\n", bitmapData->width, bitmapData->height, bitmapData->ch);
bitmapData->data =
(unsigned char*)malloc(sizeof(unsigned char) * bitmapData->width * bitmapData->height * bitmapData->ch);
if(bitmapData->data == NULL){
printf("data malloc error\n");
png_destroy_read_struct(&png, &info, NULL);
fclose(fi);
return -1;
}
for(j = 0; j < bitmapData->height; j++){
memcpy(bitmapData->data + j * bitmapData->width * bitmapData->ch, datap[j], bitmapData->width * bitmapData->ch);
}
png_destroy_read_struct(&png, &info, NULL);
fclose(fi);
return 0;
}
int pngFileEncodeWrite(BITMAPDATA_t *bitmapData, const char *filename){
FILE *fo;
int j;
png_structp png;
png_infop info;
png_bytepp datap;
png_byte type;
fo = fopen(filename, "wb");
if(fo == NULL){
printf("%sは開けません\n", filename);
return -1;
}
png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
info = png_create_info_struct(png);
if(bitmapData->ch == 3) {
type = PNG_COLOR_TYPE_RGB;
} else if(bitmapData->ch == 4) {
type = PNG_COLOR_TYPE_RGB_ALPHA;
} else {
printf("ch num is invalid!\n");
png_destroy_write_struct(&png, &info);
fclose(fo);
return -1;
}
png_init_io(png, fo);
png_set_IHDR(png, info, bitmapData->width, bitmapData->height, 8, type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
datap = png_malloc(png, sizeof(png_bytep) * bitmapData->height);
png_set_rows(png, info, datap);
for(j = 0; j < bitmapData->height; j++){
datap[j] = png_malloc(png, bitmapData->width * bitmapData->ch);
memcpy(datap[j], bitmapData->data + j * bitmapData->width * bitmapData->ch, bitmapData->width * bitmapData->ch);
}
png_write_png(png, info, PNG_TRANSFORM_IDENTITY, NULL);
for(j = 0; j < bitmapData->height; j++){
png_free(png, datap[j]);
}
png_free(png, datap);
png_destroy_write_struct(&png, &info);
fclose(fo);
return 0;
}
int freeBitmapData(BITMAPDATA_t *bitmap){
if(bitmap->data != NULL){
free(bitmap->data);
bitmap->data = NULL;
}
return 0;
}
特に PNG の読み込みを行う pngFileReadDecode
関数と、PNG の書き込みを行う pngFileEncodeWrite
関数の詳細を解説していきます。
PNG ファイルの読み込みを行う関数
pngFileReadDecode
関数は PNG ファイルの読み込みを行う関数になります。
pngFileReadDecode
の処理の流れは下記の通りです。
- シグネチャの読み込み
- PNG ファイルかどうかの判断
- 必要な構造体の生成
- シグネチャサイズの設定
- PNG ファイルの読み込み
- 画像情報取得
- BITMAP をメモリへコピー
- 生成した構造体の削除
ここから各処理の詳細を解説していきます。
シグネチャの読み込み
下記では PNG ファイルのシグネチャ部分の読み込みを行っています。
PNG ではファイルの先頭の8バイトはシグネチャというデータであり、PNG であることを示すデータが格納されています。
なので、先頭の8バイトを調べることで、そのファイルが PNG ファイルであるかを調べることができます。
fread
関数に指定している SIGNATURE_NUM
は myPng.h
で定義しているシグネチャのサイズ、つまり 8
になります。
fi = fopen(filename, "rb");
if(fi == NULL){
printf("%sは開けません\n", filename);
return -1;
}
readSize = fread(signature, 1, SIGNATURE_NUM, fi);
PNG ファイルかどうかの判断
下記では読み込むファイルが PNG かどうかの判断を行っています。
PNG でないファイルの場合は libpng でデコードできないので、PNG でない場合は関数を終了させています。
if(png_sig_cmp(signature, 0, SIGNATURE_NUM)){
printf("png_sig_cmp error!\n");
return -1;
}
必要な構造体の生成
下記では png_read
構造体と png_info
構造体の生成を行っています。
この2つは PNG の読み込みやデコード処理に必要で、今後の処理は主にこの2つを用いて実行していくことになります。
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
info = png_create_info_struct(png);
png_create_read_struct
は png_read
構造体を生成する関数で、第1引数には libpng のバージョンである PNG_LIBPNG_VER_STRING
を指定します。
第2引数以降はエラーや警告時に特別な処理を行いたい場合には指定する必要があるようですが、今回は不要なので NULL
にしています。
png_create_info_struct
は png_info
構造体を生成する関数で、引数には事前に生成した png_read
構造体を指定します。
読み込み先ファイルの設定
下記では PNG ファイルとして読み込むファイルの設定を行っています。
png_init_io(png, fi);
シグネチャサイズの設定
次にシグネチャサイズを下記で設定します。これはおそらく、既に読み込んだサイズを指定するための処理になると思います。
png_set_sig_bytes(png, readSize);
PNG ファイルの読み込み
続いて PNG ファイルを下記で読み込んでいます。
png_read_png(png, info, PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_16, NULL);
第3引数の指定により、読み込んだ PNG の画像データの変換を行うことができます。
今回は下記の2つの指定を行っています。要は各画素の輝度値を 8
ビットで扱うための指定を行っています。
PNG_TRANSFORM_PACKING
:輝度値が1
,2
,4
ビットのデータの場合は8
ビットのデータに変換するPNG_TRANSFORM_STRIP_16
:輝度値が16
ビットのデータの場合は8
ビットのデータに変換する
画像情報取得
下記では読み込んだ PNG から画像データの情報を取得しています。
width = png_get_image_width(png, info);
height = png_get_image_height(png, info);
datap = png_get_rows(png, info);
type = png_get_color_type(png, info);
datap
には PNG を BITMAP にデコードしたデータのアドレスが格納されます(この時点でデコードが行われています)。より具体的には、各ライン(各行)のデータのアドレスへのポインタになります。
type
は PNG の色の形式を表しており、このプログラムでは RGB と RGB+α のみをサポートしています。
BITMAP をメモリへコピー
下記では PNG のデコード結果である BITMAP データを事前に malloc 関数で確保したメモリへのコピーを行っています。
各ラインごとに memcpy 関数でコピーしています。
for(j = 0; j < bitmapData->height; j++){
memcpy(bitmapData->data + j * bitmapData->width * bitmapData->ch, datap[j], bitmapData->width * bitmapData->ch);
}
生成した構造体の削除
以上で PNG をデコードした BITMAP データが取得できたことになりますので、最後に生成した構造体を下記で削除しています。
png_destroy_read_struct(&png, &info, NULL);
スポンサーリンク
PNG ファイルの書き込みを行う関数
pngFileEncodeWrite
関数は PNG ファイルの書き込み(保存)を行う関数になります。
pngFileEncodeWrite
の処理の流れは下記の通りです。
- 必要な構造体の生成
- 書き込み先ファイルの設定
- 色情報の設定
- ヘッダの設定
- 画像情報を
BITMAPDATA_t
へ格納 - エンコード&ファイル書き込み
- 生成した構造体の削除
ここから各処理の詳細を解説していきます。
必要な構造体の生成
下記では読み込み時同様に、png_write
構造体と png_info
構造体の生成を行っています。
この2つは PNG の書き込みやエンコード処理に必要で、今後の処理は主にこの2つを用いて実行していくことになります。
png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
info = png_create_info_struct(png);
書き込み先ファイルの設定
続いて下記で書き込み先のファイルの設定を行っています。
png_init_io(png, fo);
色情報の設定
下記では作成する PNG ファイルの色情報を設定しています。
if(bitmapData->ch == 3) {
type = PNG_COLOR_TYPE_RGB;
} else if(bitmapData->ch == 4) {
type = PNG_COLOR_TYPE_RGB_ALPHA;
} else {
printf("ch num is invalid!\n");
return -1;
}
エンコードする画像の情報である BITMAPDATA_t
構造体の ch
に色数が格納されていますので、色数が 3
の時は RGB を、色数が 4
の時は RGB+α を表す色情報をそれぞれで設定しています。
ヘッダの設定
下記で作成する PNG のヘッダの設定を行っています。
png_set_IHDR(png, info, bitmapData->width, bitmapData->height, 8, type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
このヘッダには PNG の画像がどのようなものであるかを表すデータが格納されますので、png_set_IHDR
の引数には、例えばその画像の幅や高さ、輝度値のビット数などを指定して実行します。
BITMAP データの設定
下記では libpng に PNG にエンコードしてもらう BITMAP データの設定を行っています。
datap = png_malloc(png, sizeof(png_bytep) * bitmapData->height);
png_set_rows(png, info, datap);
for(j = 0; j < bitmapData->height; j++){
datap[j] = png_malloc(png, bitmapData->width * bitmapData->ch);
memcpy(datap[j], bitmapData->data + j * bitmapData->width * bitmapData->ch, bitmapData->width * bitmapData->ch);
}
png_malloc
関数でエンコードしてもらいたい BITMAP データを格納するためのメモリを確保し、さらに png_set_rows
でそのメモリのアドレスを設定し、最後にそのアドレスに BITMAP データをコピーしています。
エンコード&ファイル書き込み
下記で、先ほど設定したアドレスに格納された BITMAP データの PNG へのエンコードおよびファイル書き込みを行っています。
png_write_png(png, info, PNG_TRANSFORM_IDENTITY, NULL);
読み込み時同様に第3引数でデータの変換を行うことが可能ですが、今回はデータをそのまま書き込みするように PNG_TRANSFORM_IDENTITY
を指定しています。
生成した構造体の削除
以上で PNG のエンコードおよびファイル書き込みができたことになりますので、最後に生成した構造体を下記で削除しています。
png_destroy_write_struct(&png, &info, NULL);
作成した PNG 読み込み・書き込み関数の使用例
上記で作成した関数の使い方がイメージつくように使用例を書いてみました。
#include "myPng.h"
int main(int argc, char *argv[]){
BITMAPDATA_t bitmap;
int i, j, c;
int ave, sum;
char outname[256];
FILE *fo;
if(argc != 2){
printf("ファイル名が指定されていません\n");
return -1;
}
if(pngFileReadDecode(&bitmap, argv[1]) == -1){
printf("pngFileReadDecode error\n");
return -1;
}
printf("bitmap->data = %p\n", bitmap.data);
printf("bitmap->width = %d\n", bitmap.width);
printf("bitmap->height = %d\n", bitmap.height);
printf("bitmap->ch = %d\n", bitmap.ch);
/* グレースケールに変換 */
for(j = 0; j < bitmap.height; j++){
for(i = 0; i < bitmap.width; i++){
sum = 0;
for(c = 0; c < bitmap.ch; c++){
sum += bitmap.data[bitmap.ch * (i + j * bitmap.width) + c];
}
ave = sum / bitmap.ch;
for(c = 0; c < bitmap.ch; c++){
bitmap.data[bitmap.ch * (i + j * bitmap.width) + c] = ave;
}
}
}
sprintf(outname, "%s", "output.PNG");
if(pngFileEncodeWrite(&bitmap, outname) == -1){
printf("pngFileEncodeWrite error\n");
freeBitmapData(&bitmap);
return -1;
}
freeBitmapData(&bitmap);
return 0;
}
処理の流れ
この main
関数の処理の流れは下記の通りです。
pngFileReadDecode
関数を使用して PNG ファイルの読み込みデコード- 1. でデコードした BITMAP データに対して画像処理
- 2. 画像処理後の BITMAP データを
pngFileEncodeWrite
関数を使用してエンコード & PNG ファイルへの書き込み freeBitmapData
関数でメモリ解放して終了
画像処理
2. の画像処理では、1. でデコードした画像をグレースケールに変換しています(単純に RGB の輝度値の平均値を求めているだけ)。
画像処理をいろいろ試す場合はここをいろいろ変更して試してみると良いと思います。
/* グレースケールに変換 */
for(j = 0; j < bitmap.height; j++){
for(i = 0; i < bitmap.width; i++){
sum = 0;
for(c = 0; c < bitmap.ch; c++){
sum += bitmap.data[bitmap.ch * (i + j * bitmap.width) + c];
}
ave = sum / bitmap.ch;
for(c = 0; c < bitmap.ch; c++){
bitmap.data[bitmap.ch * (i + j * bitmap.width) + c] = ave;
}
}
}
コンパイル
このページで紹介するソースコードでは、PNG 読み込み用・書き込み用の関数を myPng.c
に作成し、それらの関数のプロトタイプ宣言をヘッダーファイルの myPng.h
で行っています。
ですので、上記のソースコードで myPng.h
のインクルードを行なっています。
違う名前にする場合は変更必要ですのでお気をつけください。
このページで紹介しているファイル名でソースコードファイルを作成している時、下記のコマンドでコンパイルとプログラムの実行が可能です。
gcc main.c -c gcc myPng.c -c gcc main.o myPng.o -o png.exe -lpng ./png.exe test.png
前にも説明していますが、重要なのはコンパイル時に -lpng
を付けることです。これは libpng にリンクするためのコンパイルオプションになります。
実行結果
引数で読み込みたい PNG ファイルへのパスを指定して実行すれば、その PNG ファイルをモノクロ化した PNG ファイル output.png が出力されます。
入力した PNG と出力結果の PNG もここに表示しておきます(このファイルであれば動作確認しています)。
・入力PNG
・出力PNG
このページに載せたソースコードはあくまで一例です。
PNGファイルを読み込んでデコードするあたりや PNG ファイルをエンコードして書き込むあたりはご自身が使いやすいようにカスタマイズしてください。
libpng が提供する関数
libpng については下記にてマニュアルが公開されています。
英語ですが、ファイルの読み込み方などがかなり詳しく説明されていますので、libpng 使ってプログラミングしたい人は一読しておくと良いと思います。
http://www.libpng.org/pub/png/libpng-1.4.0-manual.pdf
このページは libpng インストール方法や使用例の紹介を目的としたページであり、libpng のライセンス体系については私も詳しくないのでこのページでは言及していません
libpng を使用する方は自己責任で使用してください
例えば商用利用等を行う場合はライセンス体系についてご自分で調査してから使用の可否をご判断くださ
スポンサーリンク
まとめ
このページでは PNG の読み込み・書き込みを行うライブラリである libpng のインストール方法とその使い方について解説しました。
PNG は可逆圧縮フォーマットなので再保存しても劣化がありませんし、アルファチャンネルも使えるのでいろんな画像を扱った画像処理も可能です。
libpng は、そんな PNG を簡単に読み込み・書き込みできるライブラリですので、是非このページを参考にしてインストールしてみてください。
私のサイトでは他にも LibTIFF や libjpeg、libwebp のインストール方法や使い方についても解説していますので、他の画像フォーマットを利用したい方は是非下記のページも読んでみてください。
【C言語】LibTIFFのインストールと使用方法・使用例 【C言語】libjpegのインストールと使用方法・使用例 【C言語】libwebpのインストールと使用方法・使用例