zverok
zverok

Reputation: 1400

Getting RMagick/ImageMagick gravity with text

Here is Ruby code:

require 'rmagick'

include Magick

img = Image.new(300, 300)
draw = Draw.new

draw.line(0, 150, 300, 150)
draw.line(150, 0, 150, 300)

# for each of known gravity constants...
%w[NorthWestGravity NorthGravity NorthEastGravity WestGravity CenterGravity EastGravity SouthWestGravity SouthGravity SouthEastGravity].
each{|g|
  # set gravity to this value...
  draw.gravity Magick.const_get(g)
  # ...and draw text with this constant name
  draw.text 150, 150, g
}

draw.draw(img)

img.write('tmp/gravity.png')

Here is image which it produces:

For SouthEast/NorthWest and similar gravities result is as expected (text is near 150,150, moved in desired direction). But for South, North and others result is really pretty weird.

As far as I can understand from code, RMagick just translates gravity and text commands into corresponding ImageMagick drawing primitives, so, I suppose its something in ImageMagick's gravity concept that I can't get.

What is it?..

Upvotes: 1

Views: 956

Answers (1)

emcconville
emcconville

Reputation: 24429

I suppose its something in ImageMagick's gravity concept that I can't get.

What is it?..

The key to understanding what's going on is to locate the CenterGravity text.

Where is Center?

Shifted left by 150px, and down by 150px.

Now compare compare NorthWestGravity position.

Where is NorthWest?

Also translated left & down by 150px respectively. Seeing a trend?

Your issue is with this line...

draw.text 150, 150, g

The Magick::Draw API maps to MVG spec. Use Magick::Draw.push & Magick::Draw.pop to control drawing context.

Edit from comments...

For setting the origin of text to be drawing, you'll need to calculate the position after evaluation the text/type metrics.

Example.

require 'rmagick'

include Magick

img = Image.new(300, 300) {
  self.background_color = "palegreen"
}
draw = Draw.new
dotes = Draw.new # Dotes added for point of origin
dotes.fill = "red"

cursor = 1
# for each of known gravity constants...
%w[NorthWestGravity NorthGravity NorthEastGravity WestGravity CenterGravity EastGravity SouthWestGravity SouthGravity SouthEastGravity].
each{|g|
  offsetX = 150
  offsetY = cursor * 25
  dotes.circle offsetX, offsetY, offsetX+2, offsetY+2
  # Get metrics of text
  metrics = draw.get_type_metrics(img, g)
  # Full width
  if %w[NorthWestGravity WestGravity SouthWestGravity].include? g then
    offsetX -= metrics[:width]
  end
  # Full height
  if %w[SouthWestGravity SouthGravity SouthEastGravity].include? g then
    offsetY += metrics[:ascent]
  end
  # Half width
  if %w[NorthGravity SouthGravity CenterGravity].include? g then
    offsetX -= metrics[:width] / 2
  end
  # Half height
  if %w[WestGravity CenterGravity EastGravity].include? g then
    offsetY += metrics[:ascent] / 2
  end
  draw.text offsetX, offsetY, g
  cursor += 1
}
dotes.draw(img)
draw.draw(img)

img.write('output.png')

gravity with text

Upvotes: 3

Related Questions