RMagickの使い方 (How to use RMagick)
サーバーに上げてみたKaoChartは想像を遥かに超える重さで、このままでは世間様に全く申し訳が立たないので今さら真面目にRMagickのドキュメントを読んでみる。
ちなみにちょろっと読んだ結果、数倍は早くなりそうな予感。画像生成部分は修正と言うより作り直しっぽいけど。まぁとにかく作ってみたくて、中身はものっそ適当だったしなぁ。
てことで以下、訳。
......
http://www.simplesystems.org/RMagick/doc/usage.html
基本コンセプト
RMagickにおける"Hello, world"みたいなものを見てみよう。このプログラムは"Cheetah.jpg"と言う名前のファイルを読み込んで、モニタに表示する。
1. require 'RMagick' 2. include Magick 3. 4. cat = ImageList.new("Cheetah.jpg") 5. cat.display 6. exit
MS Windowsユーザ向け補足: このdisplayメソッドはMS Windowsでは動作しない。生成したイメージを見るには別にビューアーを使用すること。
一行目で、Magickモジュールを定義するRMagick.rbファイルをrequireしている。Magickモジュールには次の3つの大事なクラスが含まれる: ImageList, Image, Draw。この「基本コンセプト」のセクションではImageListとImageクラスについて説明する。Drawクラスについては下の「イメージを描画してテキストを追加する」セクションで説明している。
5行目ではimagelistを生成して、カレントディレクトリのCheetah.jpgファイルを読み込んで初期化し、6行目でそれのdisplayメソッドを呼び出す。imagelistにdisplayメソッドを送るとimagelistに含まれる全ての画像がデフォルトのX Windowスクリーンに表示される。今回は、displayメソッドによってチーターの画像がモニタに表示される。
早速このプログラムを打ち込んで実行してみよう。Cheetah.jpgファイルはRMagickのドキュメントをインストールしたディレクトリの下のex/imagesにある。
ImageとImageListクラスは密接に関連している。Imageオブジェクトは一枚の画像か、もしくは複数のフレームを持つ画像の一フレームをあらわす。(複数フレームを持つ画像の例としては、アニメーションGIFや、複数レイヤをもつPhotoshopイメージがある。)ImageオブジェクトはGIFやPNG、JPEGなどの画像から生成できる。大きさを指定してスクラッチから画像を生成してもいい。画像はディスクに書き込んだり、スクリーンに表示したり、サイズや傾きを変更したり、フォーマットを変更したり、100を超えるメソッドを使ってその他いろいろ修正できる。
ImageListオブジェクトは画像のリストで、ゼロ個以上の画像とシーン番号を持つ。シーン番号は現在のイメージがどれかを示す。ImageListクラスはリストに含まれる全画像を操作するメソッドを持ち、例外もあるがImageクラスで定義される全てのメソッドも実行できる。Imageのメソッドは画像一つだけに有効なので、ImageのメソッドがImagelistに対して呼び出されたときは、シーン番号で示される現在の画像に渡される。
ImageListクラスはArrayクラスのサブクラスなので、ほとんどのArrayメソッドを利用してimagelistに含まれる画像を操作できる。例えば、<<メソッドを使ってリストに画像を追加できる。
もう一度例に戻って一つ変更してみる。
1. require 'RMagick' 2. include Magick 3. 4. cat = ImageList.new("Cheetah.jpg") 5. smallcat = cat.minify 6. smallcat.display 7. exit
違いは5行目にある。この文はimagelistにminifyメソッドを送信する。minifyメソッドはImageのメソッドで画像のサイズをオリジナルの半分に縮小する。minifyはImageのメソッドなので、ImageListクラスはカレントイメージ(だけ)にminifyを送信することに注意しよう。戻り値はサイズが半分になった新しい画像になる。
6行目はImageクラスのdisplayメソッドの例で、X Window画面に画像を一枚表示する。Image#displayはモニタに(今回は小さな)チーターの画像を表示するだろう。
次に、この小さなチーターをGIFフォーマットのファイルに変換してみる。
1. require 'RMagick' 2. include Magick 3. 4. cat = ImageList.new("Cheetah.jpg") 5. smallcat = cat.minify 6. smallcat.display 7. smallcat.write("Small-Cheetah.gif") 8. exit
7行目の文は画像をファイルに書き込む。ファイルの拡張子がgifであることに注意。画像を書き込むとき、Magickはファイルの拡張子を使って書き込むファイルフォーマットを決定する。この例で、Small-Cheetah.gifファイルはGIF形式で保存される。画像をあるフォーマットから別のフォーマットに変換するのがどんなに簡単か分かるだろ?(さらに詳細は、画像フォーマットとファイル名を参照)
ここでなぜ私は先の例の中でcat変数に、一つしか画像を含まないImageListオブジェクトではなくて、Imageオブジェクトを使わなかったんだろう。正直に言えば、別に理由はない。処理するものがたった一枚の画像なら、ImageListとImageは多くの場合交換可能だ。
注: 多くの場合、Imageのメソッドは受け取る画像を変更しない。その代わり適切に変更された新しい画像を返す。例えば、resizeメソッドは指定されたサイズの新しい画像を返す。レシーバーになる画像はなにも変更されない。(Rubyの規約に従って、レシーバーオブジェクトを変更するメソッドは、メソッド名の最後に"!"が付く。例えば、resize!メソッドはレシーバーを変更する)
画像の読み込み・書き込み・生成
君は既にImageList.newを使ってImageListを生成し、指定した名前を持つ画像ファイルで初期化できることを学んだ。実は、newは引数としてファイル名をいくつでも受け取ることができる。もしファイルが一つの画像しか含まないのなら、newはそのファイルを読み込んで、Imageを生成し、ImageListにそれを加える。もしファイルが複数のフレームを持つ画像ファイルなら、newはファイル内のそれぞれのフレームまたはレイヤーにそれらを追加する。そのあと、最後にnewはシーン番号をImageList内の最後のイメージを指すように変更する。単純な例で、一枚の画像をファイルから読んだ場合はシーン番号は0に設定される。
Image.newを使ってスクラッチから画像を生成することもできる。このメソッドは2つまたは3つの引数をとる。一番目の引数は生成される画像のカラム数(幅)で、二番目の引数は行数(高さ)になる。もし3番目が存在したら、それはFillオブジェクトだ。"空の"画像をImageListに追加したいときは、ImageList#new_imageを呼び出す。このメソッドはImage.newを使って、新しい画像をImageListに追加し、シーン番号をその新しい画像に設定する。空の画像はdrawingしたり、composingして画像を生成するのに向く。
ImageやImageListのその他多くのメソッドと同じく、Image.newもオプションのブロック引数を取り、追加のオプションをパラメータとして渡すことができる。ブロックが存在すると、Image.newはパラメータオブジェクトを生成して、そのオブジェクトのスコープでブロックに渡す。パラメータオブジェクトのクラスで定義されている属性のセッターメソッドを使ってパラメータを設定できる。例えば、新しい画像の背景色を赤く設定したい場合は次のようにbackground_color=メソッドを使用する。
require 'RMagick' include Magick # Create a 100x100 red image. f = Image.new(100,100) { self.background_color = "red" } f.display exit
パラメータブロック内ではselfを使用して、Rubyにそれが変数への代入ではなくメソッド呼び出しであることを教えること。
Image.captureを使ってXWindowスクリーンから画像を生成することもできる。このメソッドはルートウィンドウ、または名前もしくはIDで指定されるウィンドウ、もしくはマウスのドラッグ&ドロップでインタラクティブに望みのウィンドウの□領域をキャプチャできる。
ImageクラスもImageListクラスもwriteメソッドを持ち、どちらも引数として書き込むファイルの名前を受け取る。Image#writeは単純に画像をファイルに書き込む。Image#readメソッドと同様にwriteもオプショナルなブロックを受け取り、画像をどのように書き込むかパラメータで制御できる。
ImageListオブジェクトが画像を一つしか含まないときはImageList#writeはImage#writeと同じだが、複数のイメージと、マルチフレームをサポートする画像フォーマット(先に述べたようにファイル拡張子で指定される)を持つときは、Image#writeは自動的にマルチフレームイメージファイルを生成する。
例えば、以下のプログラムは3つのGIFファイルを読み込み、ImageList#writeを使ってそのファイルに含まれる画像を全て(入力されるそれぞれのファイルは複数の画像を持つことがあるのを忘れないこと)一枚のアニメーションGIFファイルに保存する。
#! /usr/local/bin/ruby -w require 'RMagick' anim = ImageList.new("start.gif", "middle.gif", "finish.gif") anim.write("animated.gif") exit
画像を表示する
RMagickではImageとImageListを表示するメソッドが3つ定義されている。ImageクラスもImageListクラスもdisplayメソッドを持つ。Image#displayメソッドはデフォルトのXWindowスクリーンに画像を表示する。画像を一つしか含まないImageListの場合、ImageList#displayはImage#displayと全く同じだけど、複数の画像を持つときは、ImageList#disoplayはそれぞれの画像を順番に表示する。どちらの場合も、表示されているウィンドウを右クリックすればオプションメニューが表示される。
ImageList#animateメソッドはimagelist内の画像を順番に繰返し表示する。アニメーションのスピードはImageList#delay=メソッドで制御できる。
画像を調べたり変更したり
imageやimagelistを生成したあと、それをどうすればいい?ImageとImageListには100を超えるメソッドが定義されていて、個別にまたはグループに対して調べたり変更したりできる。ImageListクラスに同じ名前のメソッドが定義されていなくても、Imageクラスに定義されているメソッドは全てImageListインスタンスに送れることを覚えておこう。ImageListクラスはそのメソッドをカレント画像に送り、その結果を返してくれる。
これらのメソッドは大まかに以下のグループに分類できる。ImageListメソッドの説明はこのように示される。一覧に現れるメソッドのいくつかはxMagickのあるバージョンで利用できないこともある。詳細についてはメソッドのドキュメントを参照。
ユーティリティメソッド
- <=>
- Compare 2 images
- <=>
- Compare 2 imagelists
- [ ]
- Reference an image property
- [ ]=
- Set an image property
- add_profile
- Add an ICC, IPTC, or generic profile
- changed?
- Has the image been changed?
- channel
- Extract a color channel from the image
- compare_channel
- Compare one or more channels between two images
- channel_depth
- Return the depth of the specified channel or channels
- channel_extrema
- Return the maximum and minimum intensity values for one or more channels in the image
- clone
- Return a shallow copy of the image
- clone
- Return a shallow copy of the imagelist
- color_histogram
- Count the number of times each unique color appears in the image
- copy
- Return a deep copy of the image
- copy
- Return a deep copy of the imagelist
- delete_profile
- Delete an ICC, IPTC, or generic profile
- difference
- Compute the difference between two images
- distortion_channel
- Compare one or more channels to a reconstructed image
- dup
- Return a shallow copy of the image
- dup
- Return a shallow copy of the imagelist
- each_profile
- Iterate over all the profiles associated with the image
- export_pixels
- Extract pixel data from the image into an array
- export_pixels_to_str
- Extract pixel data from the image into a string
- find_similar_region
- Search for a rectangle matching the target
- get_exif_by_entry, get_exif_by_number
- Get one or more EXIF property values for the image
- get_pixels
- Copy a region of pixels from the image
- gray?
- Are all the pixels in the image gray?
- import_pixels
- Replace pixels in the image with pixel data from an array
- monochrome?
- Are all the pixels in the image either black or white?
- opaque?
- Are all the pixels in the image opaque?
- palette?
- Is the image a PseudoClass type image with 256 colors or less?
- preview
- Show the effect of a transformation method on the image
- profile!
- Add or remove an ICM, IPTC, or generic profile from the image
- properties
- Iterate over all the properties associated with the image
- set_channel_depth
- Set the specified channel's depth
- signature
- Compute the 64-byte message signature for the image
- statistics
- Compute image statistics
- store_pixels
- Replace a region of pixels in the image
- strip!
- Strip the image of all comments and profiles
- unique_colors
- Construct an image from the unique colors
- view
- Access pixels by their coordinates.
色数を減らす
- compress_colormap!
- Remove duplicate or unused entries in the image's colormap
- grayscale_pseudo_class
- Convert the image to a grayscale PseudoClass image.
- map
- Replace the colors of the image with the nearest colors from a reference image
- map
- Replace the colors of all the images in the imagelist with the nearest colors from a reference image
- ordered_dither
- Dither the image to a predefined pattern
- posterize
- Reduce the number of colors for a "poster" effect
- quantize
- Choose a fixed number of colors to represent the image
- quantize
- Choose a fixed number of colors to represent all the images in the imagelist
サイズ変更
- change_geometry
- Compute a new constrained size for the image
- crop_resized
- Resize and crop while retaining the aspect ratio
- magnify
- Double the size of the image
- minify
- Halve the size of the image
- resample
- Resample the image to the specified horizontal and vertical resolution
- resize
- Resize the image using a filter
- resize_to_fit
- Resize the image retaining the aspect ratio
- sample
- Resize the image using pixel sampling
- scale
- Resize the image
- thumbnail
- Quickly create a thumbnail of the image
色と透明度を変更
- color_fill_to_border
- Change the color of neighboring pixels. Stop at the image's border color.
- color_floodfill
- Change the color of neighboring pixels that are the same color
- colormap
- Get or set a color in the image's colormap
- color_point
- Change the color of a single pixel in the image
- color_reset!
- Set the entire image to a single color
- cycle_colormap
- Displace the image's colormap
- erase!
- Set the entire image to a single color
- matte_fill_to_border
- Make transparent neighboring pixels. Stop at the image's border color.
- matte_floodfill
- Make transparent neighboring pixels that are the same color
- matte_point
- Make a single pixel transparent
- matte_reset!
- Make the entire image transparent
- opaque
- Change all pixels from the specified color to a new color
- pixel_color
- Get or set the color of a single pixel
- splice
- Splice a solid color into the image.
- texture_fill_to_border
- Replace neighbor pixels with pixels from a texture image. Stop at the image's border color.
- texture_floodfill
- Replace neighboring pixels that are the same color with pixels from a texture image
- transparent
- Change the opacity value of pixels having the specified color
回転・反転・せん断
- affine_transform
- Transform the image as dictated by an affine matrix
- auto_orient
- Rotate or flip the image using the EXIF orientation tag
- flip
- Create a vertical mirror image
- flop
- Create a horizontal mirror image
- rotate
- Rotate the image by the specified angle
- shear
- Shear the image along the X or Y axis, creating a parallelogram
- transpose
- Create a horizontal mirror image
- transverse
- Create a vertical mirror image
Composite
- average
- Average all the images in the imagelist into a single image
- blend
- Blend two images together
- composite
- Composite the image onto another image
- composite_affine
- Composite the image onto another image as dictated by an affine matrix
- displace
- Distort the image using a displacement map
- dissolve
- Dissolve two images into each other
- watermark
- Composite a watermark onto the image
変形
- append
- Append all the images in the imagelist into a single image
- chop
- Chop a region from the image
- coalesce
- Merge successive images in the imagelist into a new imagelist
- crop
- Extract a region from the image
- crop_resized
- Resize and crop while retaining the aspect ratio
- deconstruct
- Construct a new imagelist containing images that include only the changed pixels between each image and its successor
- flatten_images
- Merge all the images in the imagelist into a single image
- mosaic
- Inlay all the images in the imagelist into a single image
- optimize_layers
- Optimize or compare image layers
- roll
- Offset the image
- shave
- Shave regions from the edges of the image
- trim
- Remove borders from the edges of the image
Enhance
- contrast
- Enhance the intensity differences between the lighter and darker elements in the image
- contrast_stretch_channel
- Improve the contrast in the image by stretching the range of intensity values
- despeckle
- Reduce the speckle noise in the image
- enhance
- Apply a digital filter that improves the quality of a noisy image
- equalize
- Apply a histogram equalization to the image
- gamma_correct, gamma_channel
- Gamma correct the image
- level
- Adjust the levels of the image
- level_channel
- Adjust the levels of one or more channels in the image
- linear_stretch
- Stretch with saturation the image contrast
- median_filter
- Apply a digital filter that improves the quality of a noisy image
- modulate
- Change the brightness, saturation, or hue of the image
- negate, negate_channel
- Negate the colors of the image
- normalize, normalize_channel
- Enhance the contrast of the image
- reduce_noise
- Smooth the contours of an image while still preserving edge information
- adaptive_sharpen, adaptive_sharpen_channel, sharpen, sharpen_channel, unsharp_mask, unsharp_mask_channel
- Sharpen the image
- sigmoidal_contrast_channel
- Adjusts the contrast of an image channel with a non-linear sigmoidal contrast algorithm
エフェクトの追加
- adaptive_threshold
- Threshold an image whose global intensity histogram doesn't contain distinctive peaks
- add_noise, add_noise_channel
- Add random noise
- bilevel_channel
- Change the value of individual image pixels based on the intensity of each pixel channel
- black_threshold
- Force all pixels below the threshold into black
- adaptive_blur, adaptive_blur_channel, blur_image, blur_channel, gaussian_blur, gaussian_blur_channel, motion_blur, radial_blur, radial_blur_channel
- Blur the image
- colorize
- Blend the fill color with each pixel in the image
- convolve, convolve_channel
- Apply a custom convolution kernel to the image
- fx
- apply a mathematical expression to an image
- segment
- Segment an image by analyzing the histograms of the color components and identifying units that are homogeneous with the fuzzy c-means technique
- random_threshold_channel
- Change the value of individual pixels based on the intensity of each pixel compared to a random threshold.
- recolor
- translate, scale, shear, or rotate the image colors
- threshold
- Change the value of individual pixels based on the intensity of each pixel compared to threshold
- white_threshold
- Force all pixels above the threshold into white
スペシャルエフェクトの追加
- charcoal
- Add a charcoal effect
- edge
- Find edges in the image
- emboss
- Add a three-dimensional effect
- implode
- Implode or explode the center pixels in the image
- morph
- Transform each image in the imagelist to the next in sequence by creating intermediate images
- oil_paint
- Add an oil paint effect
- polaroid
- Simulate a PolaroidR instant picture
- sepiatone
- Applies an effect similar to the effect achieved in a photo darkroom by sepia toning.
- shade
- Shine a distant light on an image to create a three-dimensional effect
- shadow
- Add a shadow to an image
- sketch
- Simulate a pencil sketch
- solarize
- Apply a special effect to the image, similar to the effect achieved in a photo darkroom by selectively exposing areas of photo sensitive paper to light
- spread
- Randomly displace each pixel in a block
- stegano
- Hide a digital watermark within the image
- stereo
- Combine two images into a single image that is the composite of a left and right image of a stereo pair
- swirl
- Swirl the pixels about the center of the image
- vignette
- Soften the edges of the image to create a vignette
- wave
- Add a ripple effect to the image
- wet_floor
- Create a "wet floor" reflection of the image
Decorate
- border
- Surround the image with a solid-colored border
- frame
- Add a simulated three-dimensional border around the image
- raise
- Create a simulated three-dimensional button-like effect by lightening and darkening the edges of the image
Create thumbnail montages
- montage
- Tile image thumbnails across a canvas
Create image blobs
- from_blob
- Create an image from a BLOB
- from_blob
- Create an imagelist from one or more BLOBs
- to_blob
- Construct a BLOB from an image
- to_blob
- Construct a BLOB from all the images in the imagelist
画像のマーシャリング
ImageとImageListオブジェクトはRubyのMarshalモジュールを使ってシリアライズできる。マーシャリングはxMagickのBinary Large OBject関数ImateToBlob(ダンプ用)とBlobToImage(ロード用)を使ってサポートされる。
注
1. いくつかの画像フォーマットはダンプできないが、可能かどうかは結局試してみるしかない。
2. JPEGのような非可逆なフォーマットの画像は再現後はシグネチャが異なるためequal(<=>)を使ってオリジナルと比較してもうまくいかない。
画像上への描画とテキストの追加
DrawクラスがMagickモジュールに含まれる3つ目のメジャーなクラスだ。このクラスは大きく2種類のメソッド、drawingメソッドとannotationメソッドを定義している。
Drawing
xMagickはW3CのScalable Vector Graphics (SVG) 1.1 Specificationで定義されるコマンドと要素に非常によく似た2D描画コマンドをサポートしている。RMagickではそれぞれのコマンド(プリミティブと呼ばれる)はDrawクラスのメソッドとして実装されている。画像を描画するには単に
1. Drawクラスのインスタンスを生成して
2. 適当な引数をつけて一つ以上のプリミティブメソッドを呼び出し
3. drawメソッドを呼び出せばいい
プリミティブメソッドは直接には何も描画しない。プリミティブメソッドを呼ぶと、単にDrawオブジェクトのプリミティブリストにそのプリミティブと引数が保存されるだけだ。プリミティブリストを"実行"するには、drawを呼び出す。プリミティブを描画してもそれらは破棄されない。"canvas"として別の画像を指定してdrawをもう一度呼び出せば、別の画像にまた描画できる。もちろん一枚の画像に複数のDrawオブジェクトを描画することも可能だ。canvasはimageでもimagelistでもよく、画像ファイルを読み込んだり、ImageList#new_imageまたはImage.newで新しく作られたりする。(imagelistオブジェクトがdrawに渡されるとカレント画像に描画される。)
これはデフォルトの座標系の説明だ。原点は左上の角になる。そこからx軸は右に伸び、y軸は下に伸びる。単位はピクセルになる。0度は3時の方向で、回転は時計回りに行われる。回転の単位は通常「度」になる。
デフォルトの座標系はscaling、rotation、translationなどの変形を指定して変更できる。
(クリックすればこの画像を生成するためのRubyコードが見られる)
RMagickのプリミティブメソッドには、点、線、ベジエ曲線、楕円や四角などの図形、テキストを描画するメソッドが含まれる。図形と線は塗りつぶし色と線色を持つ。図形は透明度が0でない限り、塗りつぶし色で塗りつぶされる。もちろん線色の透明度が0でない限り、図形の線は線色で描かれる。テキストも図形と考えられ、線と塗りつぶしを持つ。その他のレンダリングプロパティとしては、線幅、アンチエイリアシング、ストロークパターン、塗りつぶしパターンが設定できる。
例として、画像の上に円を描くRubyプログラムを上げる。
1. !# /usr/local/bin/ruby -w 2. require 'RMagick' 3. 4. canvas = Magick::ImageList.new 5. canvas.new_image(250, 250, Magick::HatchFill.new('white', 'gray90')) 6. 7. circle = Magick::Draw.new 8. circle.stroke('tomato') 9. circle.fill_opacity(0) 10. circle.stroke_opacity(0.75) 11. circle.stroke_width(6) 12. circle.stroke_linecap('round') 13. circle.stroke_linejoin('round') 14. circle.ellipse(canvas.rows/2,canvas.columns/2, 80, 80, 0, 315) 15. circle.polyline(180,70, 173,78, 190,78, 191,62) 16. circle.draw(canvas)
4行目と5行目で250x250の画像を一つもつ描画用のキャンバスを作成する。HatchFillオブジェクトは10ピクセルごとに薄い灰色で線が引かれた画像で埋め尽くされる。7行目でDrawオブジェクトを作り、8-15行目のメソッド呼出でプリミティブのリストを構築して、16行目のdrawメソッドでそれを"実行"する。
strokeメソッドは8行目に見られるように線の色を設定する。普通であれば図形は塗りつぶされるが(opacity=1.0)、9行目でfill_opacityを呼び出して透明度を0に設定しているので、円の背景が透けて見える。同様にふつう線の色は不透明だけど、10行目のset_opacityでこの例ではトマト色の線が少しだけ透けるようになっている。11行目から13行目のメソッド呼出で線の幅、先端の形、角の形を設定している。
14行目のellipseメソッドはキャンバスの真ん中に半径80ピクセルの円を書くように指示している。この楕円は円の315度を占め、その開始は0度(時計の3時)の方向だ。15行目で呼び出されるpolylineが円の先端に矢頭を加えている。引数は(普通偶数個で)線が通過するポイントのx座標とy座標を指定する。
最後に、16行目のdrawメソッドで保存されたプリミティブを実行してキャンバスに描画する。
Annotation
annotateメソッドは画像上に文字を描画する。一番単純なやり方では、annotateはテキストをどこに置くかと、文字列だけが指定される。
ほとんどの場合、フォントやフォントサイズ、イタリックなどのフォントファミリー、ボールドなどの文字幅、塗りつぶしや線の色、といった文字のプロパティを設定する必要があるだろう。この要求にこたえるため、Drawクラスにはattribute writersが定義されている。annotate呼び出し前にattribute writersを呼び出して好きなテキストプロパティを設定したり、またはannotate呼び出しにブロックをつけてそこで設定もできる。
以下の例でどのようにannoateを使って下の画像を表示するかを見てみる。
http://www.simplesystems.org/RMagick/doc/ex/rubyname.gif
1. #! /usr/local/bin/ruby -w 2. require 'RMagick' 3. 4. # Demonstrate the annotate method 5. 6. Text = 'RMagick' 7. 8. granite = Magick::ImageList.new('granite:') 9. canvas = Magick::ImageList.new 10. canvas.new_image(300, 100, Magick::TextureFill.new(granite)) 11. 12. text = Magick::Draw.new 13. text.font_family = 'helvetica' 14. text.pointsize = 52 15. text.gravity = Magick::CenterGravity 16. 17. text.annotate(canvas, 0,0,2,2, Text) { 18. self.fill = 'gray83' 19. } 20. 21. text.annotate(canvas, 0,0,-1.5,-1.5, Text) { 22. self.fill = 'gray40' 23. } 24. 25. text.annotate(canvas, 0,0,0,0, Text) { 26. self.fill = 'darkred' 27. } 28. 29. canvas.write('rubyname.gif') 30. exit
このプログラムではエッチングの効果を出すためにannotateが3回呼び出されている。3回の呼び出しは塗りつぶし色と場所以外はすべて同じパラメータを持っている。
まず8-10行目で背景を生成している。TextureFillクラスの詳細についてはFillクラスを参照。"granite"画像フォーマットはxMagick組み込み画像フォーマットの一つで、詳細については久美込みフォーマットを参照。12行目の文で文字を書き込むDrawオブジェクトを生成している。そのあとの3行はannotate呼び出し全てで共通の属性値を設定する。
一番目のannotateの引数はテキストが描画される画像になる。2-5番目の引数はそれぞれテキストが描画される領域のwidth、height、x、yになる。この領域はgravityという値が設定されていて、それでテキストの位置が決まる。gravityの値がCenterGravityのときはwidthとheightは使用されない。
17-19行目の最初のannotate呼び出しは中心から2ピクセルだけ右下にずれた位置にテキストを描画する。self.fill = 'gray83' と言う文で色は淡い灰色に設定される。21-22行目のannotateでは、濃い灰色の文字が中心から1.5ピクセルだけ左上に描画される。25-27行目にある最後の呼び出しで同じ文字列が濃赤色で画像の中心に描かれる。
次に読むべきは
次のセクション"ImageMagick/GraphicsMagick Conventions"では、xMagickが画像ファイルのフォーマットをどのように決定するかなどの、知っておいた方がいい規約について述べる。ImageMagick(www.imagemagick.org)とGraphicksMagick(www.graphicsmagick.org)のウェブサイト(このページの情報はほとんどそこから得られた)ではxMagickについてたくさんの詳細な情報がある。それらのサイトはRMagickについてのべているわけではないけど、Magick APIのメソッドについて読めばRMagickのメソッドについてもたくさんのことが学べるだろう。(このドキュメントのリファレンスセクションでは、メソッドの説明のほとんどでそのメソッドが呼び出すMagick APIの名前を書いてある。)例題のプログラムもチェックしよう。ほとんど全てのメソッドがいずれかの例題で実際に使用されている。
Good luck!