使用RMagick读取图像时设置密度

3

我正在尝试使用RMagick将一个SVG转换成不同大小的PNG。

当我使用Magick::Image.read('drawing.svg')读取SVG并将其写入drawing.png(相当于从命令行中运行convert drawing.svg drawing.png)时,大小为744x1052。

假设我希望PNG的大小是默认大小的两倍。你不能只是读取它,改变它的大小,然后写出来,因为这首先会栅格化SVG,然后缩放该图像到两倍大小,失去质量和使用矢量图形的全部好处。所以,如果我理解正确,你应该在读取时设置图像的密度。

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

但是,image.density仍然报告密度为“72x72”,如果我将图像写出,则其大小与之前相同,为744x1052。似乎无论我如何指定读取密度,都没有关系。使用144、"144"、144.0、"144.0"、"144x144"和"144.0x144.0",它总是返回"72x72"。
从命令行运行convert -density 144 drawing.svg drawing.png可以按预期工作,并生成比以前大两倍的PNG,即2104x1488。
我正在使用OS X 10.6.7、ImageMagick 6.7.0-0(通过MacPorts安装)、RMagick 2.13.1和Ruby 1.9.2p180。当我将我的代码放入Heroku上的一个小Sinatra webapp的上下文中时,它具有相同的不正确行为,因此问题似乎并不在于OS X或MacPorts。
1个回答

4
密度是关于分辨率(即每英寸点数),而不是呈现尺寸。从fine manual中了解到:
“图像的垂直和水平像素分辨率。默认值为“72x72”。“
我认为您正在寻找resizeresize!
更改接收器的大小以指定的尺寸为准。可以通过两种方式指定新尺寸。要么显式指定新宽度和高度,要么指定比例因子,即代表百分比变化的数字。
所以这样做就可以:
Magick::Image.read('drawing.svg').first.resize(2).write('drawing.png')

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

我不知道为什么convert的行为与库不同,可能有其他默认设置在起作用,在库中具有不同的默认值,或者-density做了更多的工作。
如果resize对您没有用(根据您的评论,它发生得太晚了,无法使用),您可以尝试在块中设置size参数
img = Magick::Image.read('drawing.svg'){ |opts| opts.size = '2104x1488' }.first

当然,在使用SVG之前,您需要知道它的尺寸大小。你可以指定像200%x200%这样的几何形状,但是当我尝试使用read时,Magick::Geometry上的标志总是被忽略。请注意,HTML标记将保留。

1
如果我只是在进行栅格到栅格的转换,那么调整大小肯定是我想要的。但是如果我在读取SVG后调整大小,我会放大栅格图像,因此我会得到你所期望的令人讨厌的抗锯齿伪影convert命令似乎首先将SVG光栅化为较大的图像,这样就会产生正确平滑的线条 - hynkle
3
它不让我编辑我的评论,但我想提到在ImageMagick论坛中发现的一个帖子,它说“-density”的用途之一是指定矢量图像的读取密度。显然,它在RMagick中的含义与“convert”不同。 - hynkle
1
@hynkle:看看我的更新。你应该能够为opts.size指定百分比几何,但我无法使其工作或生成告诉我为什么它不起作用的错误消息。这对于我与ImageMagick的交互来说非常典型:如果你能让它工作,那么它是一个很棒的库,但界面很糟糕。 - mu is too short
@muistooshort,这似乎不再起作用了。我已经尝试过更改opts.size,但没有任何影响。 - Maximilian Ruta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接