RMagickで透過PNG画像をアルファチャンネルを保持したまま回転させる

@hammmmさんに助けられた。 http://twitter.com/hammmm/status/8988945428


こうすると、画像にアルファ値が含まれている場合は残念な壊れた画像が生成される。

img = Image.from_blob(File.read("star.png")).shift
img.rotate(45) # 45度回転

下記にどういう画像ができるかが書いてある

上のページの解説には、アルファ値を持った画像を回転させるとアルファ値が無くなってしまうと書いてあるがそうではない。
ImageMagickの仕様で、たしかにそのまま画像を回転させると残念な画像が生成されてしまうが、
http://www.imagemagick.org/discourse-server/viewtopic.php?f=10&t=13600 に書いてあるとおりSetBackgroundColorにnoneを指定してから回転すれば大丈夫だった。


つまりアルファ値が無くなるというより、回転後の画像が貼り付けられるImageオブジェクトのアルファ値の初期値がnoneではない事が原因になっている。たぶんPerlImageMagickラッパーではblackが初期値で、RubyのラッパーのRMagickではwhiteが初期値になっている。


なので、初期値を与えてやればいい。
新しく背景無しのImageオブジェクトを作ってそこにPNG画像をcompositeで貼り付けてから回転させれば良い。

img = Image.from_blob(File.read("star.png")).shift
img = Image.new(img.columns, img.rows){self.background_color = 'none'}.composite(img, 0, 0, OverCompositeOp).rotate(45) # 45度回転


Imageを新しく作っているのは、

img.background_color = 'none'
img.rotate!(@rotate)

としても動くんだけど、なぜかどんどん画像が小さくなり、メモリをすごい勢いで食っていって

ruby(4965) malloc: *** mmap(size=1692827648) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug

というエラーで落ちるから。(Macの場合)