2011年05月15日

Magick++で画像のピクセル列を書き換える

OS:Mac OS X Leopard(10.5.6)
言語:C/C++
ライブラリ:Magick++ (ImageMagick)

Magick++とC++を使うことで、画像のピクセル列にアクセスして値を参照したり書き換えたりできます。他の言語のImageMagickインターフェースでできるかはわかりませんが、ピクセル列の値を書き換えるとかっていかにもC++で画像処理しているっていう感覚で楽しいですし、既存のクラスやメソッドに無い処理を実装する場合には便利ですね。

100×100の青い画像を作成して、画像の左上(全体の1/4)をグラデーションにするプログラムを書いてみました。
#include <Magick++.h>
using namespace std;
using namespace Magick;

int main(int argc,char **argv)
{
    const int width = 100;
    const int height = 100;

    Image image(Geometry(width, height), ColorRGB(0, 0, 1));
    image.type(TrueColorType);
    image.modifyImage();
    Pixels view(image);
    PixelPacket* pixels = view.get(0, 0, width / 2, height / 2);

    for (int i = 0; i < height / 2; i++) {
        for (int j = 0; j < width / 2; j++) {
            pixels[i*(width / 2)+j] = ColorRGB(1, 0, (double)j / (double)(width / 2));
        }
    }

    view.sync();
    image.write("sample.png");

    return 0;
}

作成した画像からピクセル列を生成するにはMagick::Viewクラスを使います。コンストラクタにMagick::Imageクラスのインスタンスを渡すことで、その画像のピクセル列の領域がメモリに確保されます。
生成したピクセル列からポインタを取得するには、Magick::Viewクラスのget関数を使います。
PixelPacket* Magick::View::get(
    const ssize_t x_,
    const ssize_t y_,
    const ssize_t columns_,
    const size_t rows_
)


画像中の位置をx_とy_に指定して、x_とy_からの領域の大きさをcolumns_とrows_に指定します。この例では、画像の左上から縦横それぞれ50ピクセル分のピクセル列のポインタを取得しています。
元の画像(Magick::Imageクラスのインスタンス)にピクセル列の内容を反映させたい場合は、Magick::Viewクラスのsync関数を使います。この関数は呼ぶだけです。
最後にMagick::Imageクラスのwrite関数で画像ファイルとして出力しています。以下のような画像になります。
view


2011年05月08日

ImageMagickで日本語の文字列を画像に描画

OS:Mac OS X Leopard(10.5.6)
ソフト:ImageMagick

Magick++とC++で画像を生成して、そこに日本語を描画させようとしたのですが、どうにも上手くいかないので、別のやり方でやってみました。ImageMagickのconvert コマンドです。

convertコマンドで日本語を描画する場合の注意点として2つあると思います。
注意点1
フォントは日本語に対応しているものをパスを含めたフォントのファイル名で指定する
注意点2
描画したい文字列はUTF-8で保存したファイルで用意する

説明だけではピンとこないので、いつくかコマンド例を示します。


成功例-フォントも文字列もきちんと指定


フォントの指定も、描画する日本語の指定も問題がない場合を以下に示します。背景は白、文字の色は黒です。
convert -background white -fill black -font "/System/Library/Fonts/ヒラギノ角ゴ ProN W3.otf" label:@input.txt text.png

-fontの後にフォントのファイルを指定します。文字列はlabelの後に@を付けてファイル名を指定します。最後に、出力する画像のファイル名を指定します。
以下の画像が生成されます(「こんにちわ」って描画されています)。
text



失敗例-フォントのパスが間違い


-fontに間違ったパスを指定した場合です。
convert -background white -fill black -font "ヒラギノ角ゴ ProN W3.otf" label:@input.txt text.png

これを実行すると以下のようなワーニングが出ます(text.pngは生成されます)。
convert: unable to read font `ヒラギノ角ゴ ProN W3.otf' @ warning/annotate.c/RenderType/879.

フォントファイルが読み込めませんということですね。
画像は生成されるのですが、正しく描画されません。以下のようになります(「?????」って描画されています)。
text_error
それと、フォントに関してですが、フォントを指定しなくても「?????」が生成されます。


おまけ-日本語を直接指定でもOK


私のMacはターミナルの文字コードがUTF-8だからだと思うのですが、labelに文字列を直接指定しても正しく描画されました。以下がコマンドです。
convert -background white -fill black -font "/System/Library/Fonts/ヒラギノ角ゴ ProN W3.otf" label:直接こんいちわ text.png

text.pngには「直接こんいちわ」と描画されています。この方法だとWindowの方はどうなんでしょう?やっぱり、ファイルをUTF-8で保存する方が良いのかな?

2011年05月05日

Magick++で画像を作成して出力

OS:Mac OS X Leopard(10.5.6)
ライブラリ:Magick++(ImageMagick)
言語:C++

ImageMagickのC++用のインターフェースをMagick++といいます。Magick++を使うと、ImageMagickの機能をC++のクラスとして利用できます。

今回は、Magick++を使って、画像を作成してファイルに出力するプログラムを試してみました。

以下がC++のソースコードです。
#include <Magick++.h>
using namespace std;
using namespace Magick;

int main(int argc, char **argv)
{
    Image image("100x100", ColorRGB(0, 0, 1));
    image.pixelColor(49, 49, ColorRGB(1, 0, 0));
    image.write("sample.png");

    return 0;
}

画像を生成したり、ファイルから読み込む場合はMagick::Imageクラスを使います。このクラスのコンストラクタに画像のサイズと色を指定します。ここでは、100×100ピクセルの青い画像を生成しています。
Magick::Image::pixelColorメソッドで、指定したピクセルに色を設定します。ここでは、(49, 49)の位置のピクセルを赤にしています。
最後に、Magick::Image::writeで画像ファイルとして出力します。
下のような画像が出力されます。
sample

次にmakeファイルです。
INCLUDE_DIR = /opt/local/include/ImageMagick
LIB_DIR = /opt/local/lib

main: main.o
    g++ -o main -I$(INCLUDE_DIR) -L$(LIB_DIR) main.o -lMagick++ -lMagickCore -lMagickWand -lX11

main.o: main.cpp
    g++ -c -I$(INCLUDE_DIR) main.cpp

.PHONY: clean
clean:
    rm -f main.o main

実はmakeファイルの方が苦労しました。いろいろ試してみたのですが、libMagick++.a、libMagickCore.a、libMagickWand.a、libX11.aをリンクすれば大丈夫なようです。ヘッダーファイル(INCLUDE_DIR)やライブラリ(LIB_DIR)の場所は、環境に依ると思うので気をつけて下さい。


Mac OS X にImageMagickをインストール

OS:Mac OS X Leopard(10.5.6)
ソフトウェア:ImageMagick

ImageMagickは、多様な形式の画像ファイルを扱える便利な画像処理プログラムです。画像処理というと、GUIでマウスを使って...と思いがちですが、これはコマンドラインから画像を読み込んで処理するCUIのプログラムです。
大量の画像ファイルを別の形式に一括変換するなどの処理を行う場合に便利です。

そういうわけで、ちょっとMacに入れてみました。

最初はソースを落としてきて、自分でmakeしてみましたが、(インストールは出来たのに)上手く動きませんでした(他のライブラリが足りなかったのかな?)。Macに入れる場合、MacPortsを使ってインストールするのが良いようです。MacPortsとは、パッケージ管理ツールで、主要なツールやライブラリはMacPortsを使えば大抵揃うらしいです。

1. MacPortsのインストール


MacPortsをインストールする前に、Xcodeをインスロールする必要があります。Xcodeはインストールディスク(OSが入っているやつです)からインストールして下さい。
次にこちらからバージョンに合ったdmgファイルをダウンロードしてインストーラを起動するとインストールできます。

インストールしたら、パスを通します。ホームディレクトリに移動して、.bash_profileファイルに以下の内容を追加します。
export PATH=/opt/local/bin:/opt/local/sbin/:$PATH
export MANPATH=/opt/local/man:$MANPATH


2. ImageMagickのインストール


ターミナルを起動して
>sudo port install ImageMagick
でインストールできます。必要なライブラリなども一緒に入るので便利です。環境にも依ると思いますが、結構時間がかかります(私は軽く1時間以上かかった)。



ImageMagickは他の言語から使えたりと幅が広いです。とりあえず、C++から使えるMagick++というライブラリ(ImageMagickと一緒にインストールされました)の使い方を覚えたいです。