non vorrei lavorare

ブログ名の通りです。javascript three.js mruby rust OCaml golang julialang blender

mruby-mrmagickをGraphicsMagickに対応させた

こんにちは、今週も奥さんが出張です。しかも、長男がまた発熱というおまけつきです。不幸中の幸いというか、長男はインフルは陰性でした。kjunichiです。

背景

Ubuntu 16.04LTSで素の状態ではGraphicsMagickが使われることを先日の記事で学んだ。

CIはTravis-CIでLinux上で回してるからてっきりGraphicsMagickでも動くものと思い込んでいた。 しかし、実際には先日のUbuntu 16.04LTSのGraphicsMagick環境ではmruby-mrmagickは動かなかった。。

github.com

GraphicsMagickに対応する為に必要だった2点

  • InitializeMagickを初期化時にちゃんと呼ぶ
  • 有無の分からないEXIF情報取得にImage#profileを使わない

InitializeMagickを初期化時にちゃんと呼ぶ

これまでのコードは、もう書いてからずいぶん時間が経過しており、記憶に内が、 なんとなく、レイトバインディングな考えで、必要になるまで余計なことをやらない方針だったと思う。

その為、ImageMgaickの初期化も、必要な個所まで引き延ばそうとした作り出ったし、 必要なところ(動かすと落ちる)の直前で初期化を実施するつくりにしていた模様。

今回GraphicsMagickに対応するに当たり、これをmrbgemの初期化時に行うように変更した。

有無の分からないEXIF情報取得にImage#profileを使わない

GraphicsMagickのMagick++ APIではImage#profileをJPEGでもEXIFが無い画像に対して行うと、落ちる。

'Magick::ErrorCoder'
what(): Magick: No APP1 data is available () reported by coders/meta.c:2369 (WriteMETAImage)

当初、この箇所が分からず、回転操作関連のテストで落ちるだけしか分からなかったが、 なんとか、再現コードまで辿り着け、問題解決につながった。

再現コード

#include <iostream>
#include <Magick++.h>

using namespace std;
using namespace Magick;

int main(int argc, char **argv) {
InitializeMagick(*argv);
Image img;
img.read("output.png");

Blob blob = img.profile("EXIF");

if (blob.data() == NULL) {
  cout << "exif == NULL"<<endl;
  static unsigned char dexifData[] = {
    69, 120, 105, 102, 0, 0, 77, 77, 0, 42, 0, 0, 0, 8, 0, 9, 1, 15, 0, 2, 0};
  Blob exifdata(dexifData, 3);

  img.profile("exif", exifdata);
}
return 0;
}

ビルド

g++ -o test05 test05.cpp `GraphicsMagick++-config --cppflags --libs --ldflags`
convert -size "640x480" -background "#C0C0C0" -fill "#FFFF00" caption:"ABC" output.jpg
./test05

幸い、EXIFのカメラの回転情報といったより、具体的な項目を指定するImage#orientationメソッドではGraphicsMagickでも落ちずに0が返される 動きだったので、こちらを使う事で対応出来た。

-    Blob blob = img->profile("exif");
-    if (blob.data() == NULL) {
-      // we generate dummy exif data.
+    if(img->orientation() == 0) {
       Blob exifdata(dexifData, dexifDataLength);
       img->profile("exif", exifdata);
-      // make own exif data.
     }

関連記事

13年前の記事

7年前の記事

4年前の記事

2年前の記事