如何在Ruby中合并图像

9

我有4个正方形图像,分别是1、2、3和4,每个图像都是2048x2048px。

我需要将它们合并成一个4096x4096px的图像,就像这样:

 1 2
 3 4

目前我在使用Gimp手动操作,但是处理的数量不断增加,我想实现一个自动化解决方案。

在Ruby中有没有简单的方法?(Rails gem也可以,或者是可以从Rails应用程序内部运行的任何shell命令)


2
我会推荐使用 rmagick,它是一个非常强大的图像处理器。 - dax
通过组合图像,你的意思是从4张图像制作出一张图像吗?可以尝试使用rmagick。 - Surya
尝试使用复合!https://rmagick.github.io/image1.html#composite_bang - Ollie
4个回答

6
尝试使用“rmagick”宝石: 'rmagick' gem
require 'rmagick'

image_list = Magick::ImageList.new("image1.png", "image2.png", "image3.png")
image_list.write("combine.png")

你也可以参考这个SO问题,它与你的问题类似。


1
顺便提一下,rmagick gem 还需要你安装 ImageMagick,它才能完成实际的工作(rmagick 只是为 ImageMagick 提供了友好的 Ruby 接口)。传统上安装 ImageMagick 通常很麻烦(无论我怎么做都是这样),但现在我认为安装要容易得多。 - Max Williams
@MaxWilliams:是的,我同意你的观点。应该安装ImageMagick - Gagan Gami
1
我尝试过了,但是我得到了一个2048x2048的图像,其中每个图像都在另一个图像的顶部。我不想让它们在顶部,我需要第一个在0,0的位置,第二个在0,2048的位置,第三个在2048,0的位置,最后一个在2048,2048的位置。基本上,我想从4个较小的正方形图像中组成一个正方形图像,每个图像都是新图像的四分之一。 - Eduard

6

我标记了被接受的答案,因为它为解决我的问题提供了起点。我也会在这里发布完整的工作解决方案:

require 'rmagick'
class Combiner
include Magick

  def self.combine
    #this will be the final image
    big_image = ImageList.new

    #this is an image containing first row of images
    first_row = ImageList.new
    #this is an image containing second row of images
    second_row = ImageList.new

    #adding images to the first row (Image.read returns an Array, this is why .first is needed)
    first_row.push(Image.read("1.png").first)
    first_row.push(Image.read("2.png").first)

    #adding first row to big image and specify that we want images in first row to be appended in a single image on the same row - argument false on append does that
    big_image.push (first_row.append(false))

    #same thing for second row
    second_row.push(Image.read("3.png").first)
    second_row.push(Image.read("4.jpg").first)
    big_image.push(second_row.append(false))

    #now we are saving the final image that is composed from 2 images by sepcify append with argument true meaning that each image will be on a separate row
    big_image.append(true).write("big_image.jpg")
  end
end

3

如果你是通过谷歌搜索来到这里的,并且使用的是更新版本的 MiniMagick (4.8.0)Rails (5.2.0),以下代码可以帮助你将图片水平合并:

# Replace this with the path to the images you want to combine
images = [
  "image1.jpg",
  "image2.jpg"
]

processed_image = MiniMagick::Tool::Montage.new do |image|
  image.geometry "x700+0+0"
  image.tile "#{images.size}x1"
  images.each {|i| image << i}
  image << "output.jpg"
end

请查看文档了解有关#geometry选项的信息,以处理调整大小和布局。当前示例将调整图像的大小以使其高度为700px,同时保持图像的纵横比。使用+0+0将在图像之间没有留下空隙的情况下放置图像。


我还没有查看代码内部,但是这可能比在 &block 中使用 File.open 更节省内存。 - Myk Klemme
使用 tile 选项来实现问题所需的布局。image.tile "2x2" - Myk Klemme
将 proccessed_image 转换为 blob,您需要在末尾添加 image.stdout。 - Ben-Hur Batista

1
你可以尝试使用 montage 方法。

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