将图像裁剪为矢量形状或覆盖形状

时间:2014-03-27 05:27:19

标签: ruby-on-rails ruby imagemagick

我想这是一个黑暗中的镜头,但是有可能有一个形状的矢量文件(在这种情况下是一个圆角的六边形),并通过一些代码传递图像并让它出来裁剪那个载体的形状?

我试图在我的设计中使用六边形,并且我可能已经浏览了每一页。我已经看过许多HTML和CSS解决方案,但它们都没有达到我正在寻找的完美无缺。

我的另一个想法是,可以在imagemagick上覆盖现有图像顶部的透明六边形和白色角,然后穿过并使任何白色透明。思考?

我没有任何用于裁剪矢量文件形状的代码,但这里有我在另一张图片上覆盖我想要的形状轮廓的内容:

imgfile = "public/" + SecureRandom.uuid + ".png"
SmartCropper.from_file(art.url(:original)).smart_square.resize(225,225).write(imgfile)

overlay = Magick::Image.read("app/assets/images/overlay.png")
img = Magick::Image.read(imgfile)         
img.composite(overlay,0,0, Magick::OverCompositeOp)

现在它给了我一个未定义的复合方法错误,这很奇怪,因为我在他们的模型中使用相同的东西跟着其他一些堆栈溢出问题。

感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

您已陷入常见的ImageMagick陷阱 - 您从.read方法获得的对象不是Magick::Image个对象,而是Magick::ImageList个对象,对于大多数图像类型,您需要第一个项目从列表中。

在不知道如何设置 overlay.png 文件的情况下,很难说出最佳复合选项是什么。但是,在类似的情况下,我发现CopyOpacityCompositeOp很有用,并且让叠加层的透明度控制最终图像的透明度。

我测试了以下代码,如果 overlay.png 以这种方式设置,它看起来会像你想要的那样:

require 'smartcropper'

imgfile = "test_square.png"
SmartCropper.from_file( 'test_input.png' ).
    smart_square.resize( 225, 225 ).write( imgfile )

overlay = Magick::Image.read( 'overlay.png' ).first

img = Magick::Image.read( imgfile ).first

img.composite( overlay, 0, 0, Magick::CopyOpacityCompositeOp ).
    write( "test_result.png" )

您可以使用overlay创建文件,而不是从文件中读取Magick::Draw

overlay = Magick::Image.new( 225, 225 ) do |i|
  i.background_color= "Transparent"
end

gc = Magick::Draw.new
gc.stroke('white').stroke_width(10)
gc.fill('white')
gc.polygon(97.5, 26.25, 178.5, 73.125, 178.5, 167, 
    97.5, 213.75, 16.5, 167, 16.5, 73.125)
gc.draw( overlay )

请注意,这是一个六边形,但我并没有打扰它的中心。