RMagickで透過PNG画像をアルファチャンネルを保持したまま回転させる
@hammmmさんに助けられた。 http://twitter.com/hammmm/status/8988945428
こうすると、画像にアルファ値が含まれている場合は残念な壊れた画像が生成される。
img = Image.from_blob(File.read("star.png")).shift img.rotate(45) # 45度回転
下記にどういう画像ができるかが書いてある
- http://www23.atwiki.jp/selflearn/pages/47.html
- http://www.imagemagick.org/discourse-server/viewtopic.php?f=10&t=13600
上のページの解説には、アルファ値を持った画像を回転させるとアルファ値が無くなってしまうと書いてあるがそうではない。
ImageMagickの仕様で、たしかにそのまま画像を回転させると残念な画像が生成されてしまうが、
http://www.imagemagick.org/discourse-server/viewtopic.php?f=10&t=13600 に書いてあるとおりSetBackgroundColorにnoneを指定してから回転すれば大丈夫だった。
つまりアルファ値が無くなるというより、回転後の画像が貼り付けられるImageオブジェクトのアルファ値の初期値がnoneではない事が原因になっている。たぶんPerlのImageMagickラッパーでは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の場合)