【问题标题】:Port ImageMagick commands to RMagick将 ImageMagick 命令移植到 RMagick
【发布时间】:2012-05-24 12:20:42
【问题描述】:

我正在使用 ImageMagick 命令进行图像处理,我想将它们移植到 RMagick。此任务的目标是拍照并像素化给定区域(一个或多个)以保护隐私。

这是我的 bash 脚本 (script.sh),使用 convert 命令效果很好:

convert invoice.png -scale 10% -scale 1000% pixelated.png
convert invoice.png -gamma 0 -fill white -draw "rectangle 35, 110, 215, 250" mask.png
convert invoice.png pixelated.png mask.png -composite result.png

现在我想使用 ImageMagick 创建这个脚本的 Ruby 版本。这是我现在拥有的:

require 'rmagick'

# pixelate_areas('invoice.png', [ [ x1, y1, width, height ] ])
def pixelate_areas(image_path, areas)
  image     = Magick::Image::read(image_path).first
  pixelated = image.scale(0.1).scale(10)
  mask      = Magick::Image.new(image.columns, image.rows) { self.background_color = '#000' }

  areas.each do |coordinates|
    area = Magick::Image.new(coordinates[2], coordinates[3]) { self.background_color = '#fff' }
    mask.composite!(area, coordinates[0], coordinates[1], Magick::OverCompositeOp)
  end

  # Now, how can I merge my 3 images?
  # I need to extract the part of pixelated that overlap with the white part of the mask (everything else must be transparent).
  # Then I have to superpose the resulting image to the original (it's the easy part).
end

如您所见,我被困在最后一步。我需要对my original picturemy pixelated picturemy mask进行什么操作才能拥有this result

我怎样才能构建一个只有蒙版的白色部分和像素化图片重叠的图像。就像this one 一样,但是透明而不是黑色?

【问题讨论】:

  • 没有错误。我只是不知道如何处理我的原始图像、图像的像素化版本和蒙版。我在帖子中添加了图片。

标签: ruby imagemagick rmagick


【解决方案1】:

首先,当你有一些已经可以工作的东西时,你为什么要将命令移植到 RMagick? bash 版本简短易懂。如果这只是您要移植的较大脚本的一部分,请不要害怕system()

也就是说,这是一种不同的策略,我相信它可以以更直接的方式完成您尝试做的事情。

require 'RMagick'

def pixelate_area(image_path, x1, y1, x2, y2)
  image          = Magick::Image::read(image_path).first
  sensitive_area = image.crop(x1, y1, x2 - x1, y2 - y1).scale(0.1).scale(10)

  image.composite!(sensitive_area, x1, y1, Magick::AtopCompositeOp)
  image.write('result.png') { self.depth = image.depth }
end

这似乎和你原来的 bash 命令一样:

pixelate_area('invoice.png', 35, 110, 215, 250)

由于您似乎想要处理多个区域以进行模糊处理,因此这里有一个版本,它采用一组区域(每个区域为 [x1, y1, x2, y2]):

def pixelate_areas(image_path, areas)
  image = Magick::Image::read(image_path).first

  areas.each do |area|
    x1, y1, x2, y2 = area

    sensitive_area = image.crop(x1, y1, x2 - x1, y2 - y1).scale(0.1).scale(10)
    image.composite!(sensitive_area, x1, y1, Magick::AtopCompositeOp)
  end

  image.write('result.png') { self.depth = image.depth }
end

【讨论】:

  • 谢谢达山,我会试试的。我想将它转换为 Rmagick 的原因是我会将临时文件保存在 RAM 中以避免多个处理之间的冲突。我相信我可以防止每次转换都使用随机目录,但在 RAM 中更简单。
  • @RomainTribes mktemp 对于在这种情况下避免名称冲突很有用。并不是说我实际上建议坚持使用 shell 脚本;我认为 Ruby 版本更灵活,更易于使用。我只是想确保您知道您可以选择只使用现有的工作命令。这通常是最简单且完全足够的。
  • @RomainTribes 顺便说一句:您可以将 stdin 和 stdout 与 convert 一起使用,以避免来自 shell 命令的临时文件,例如convert -rotate 90 - png:fd:1 该命令将旋转您传递给标准输入的任何内容(第一个 - 实现了这一点),并将其作为 png 输出到标准输出(png:fd:1 实现了这一点)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-09
  • 1970-01-01
  • 2011-06-21
  • 1970-01-01
  • 1970-01-01
  • 2012-08-01
  • 2013-08-19
相关资源
最近更新 更多