开发者

setting density upon image read with RMagick

I am attempting to use RMagick to convert an SVG to a PNG of a different size.

When I read in the SVG with Magick::Image.read('drawing.svg') and write it out to drawing.png (the equivalent of just running convert drawing.svg drawing.png from the command line), the size is 744x1052.

Let's suppose I want the PNG to be twice as large as it is by default. You can't just read it in, resize it, then write it out, as that first rasterizes the SVG and then scales that image to be twice as large, losing quality and the entire benefit of using a vector graphic in the first place. So instead, if I understand correctly, you're supposed to set the image's density upon read.

image = Magick::Image.read('drawing.svg'){self.density = 144}.first

But image.density still reports the density as "72x72", and if I write out the image it has the same size as before, 744x1052. It doesn't seem to matter how I specify the density upon read. With 144, "144", 开发者_StackOverflow中文版144.0, "144.0", "144x144", and "144.0x144.0", it always comes back "72x72".

Running convert -density 144 drawing.svg drawing.png from the command line works as expected and generates a PNG that's twice as large as before, 2104x1488.

I'm using OS X 10.6.7, ImageMagick 6.7.0-0 (installed via MacPorts), RMagick 2.13.1, and Ruby 1.9.2p180. When I put my code into the context of a little Sinatra webapp on Heroku, it has the same incorrect behavior, so the issue does not seem to lie with OS X or MacPorts.


Density is about resolution (i.e. dots per inch), not the rendered size. From the fine manual:

The vertical and horizontal resolution in pixels of the image. The default is "72x72".

I think you're looking for resize or resize!:

Changes the size of the receiver to the specified dimensions.

You can specify the new size in two ways. Either specify the new width and height explicitly, or specify a scale factor, a number that represents the percentage change.

So this will work:

Magick::Image.read('drawing.svg').first.resize(2).write('drawing.png')

Or this:

img = Magick::Image.read('drawing.svg').first
img.resize!(2)
img.write('drawing.png')

I don't know why convert behaves differently than the library, there could be other default settings in play that have different defaults in the library or maybe -density does more than set the density.

If resize isn't doing the trick for you (and, based on your comments, it is happening too late to be of use), you can try setting the size parameter in the block:

img = Magick::Image.read('drawing.svg'){ |opts| opts.size = '2104x1488' }.first

Of course, you have to know how big the SVG is before hand. You're supposed to be able to specify things like 200%x200% for the geometry but read always ignores the flag on the Magick::Geometry when I try it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜