在数组Ruby中保存像素颜色

时间:2018-05-01 23:15:02

标签: ruby minimagick

我使用CarrierWave和MiniMagick处理图像。我上传图片。现在我需要获取图像中所有像素的值并将它们存储到数组

如果我使用下一个代码,那么效果很好

def pixelcolor 
@image = MiniMagick::Image.open(image.path)     
return @image.get_pixels[56][34][1] # 56 and 34 - random numbers for row and column
end

下一个代码也适用

def pixelcolor 
@image = MiniMagick::Image.open(image.path)     
width = @image.width
color = Array.new   
for i in 0..width
  color[i] = i
end
return color
end

但如果我尝试做下一个代码就行不通了

def pixelcolor 
@image = MiniMagick::Image.open(image.path)     
width = @image.width
color = Array.new
for i in 0..width
    color[i] = @image.get_pixels[45][65][0]
end
return color
end

结果我需要这样的东西

def pixelcolor 
@image = MiniMagick::Image.open(image.path)     
width = @image.width
height = @image.height  
red = Array.new  
green = Array.new
blue = Array.new    
for i in 0..width
    for j in 0..height
      red[i][j] = @image.get_pixels[width][height][0]
      green[i][j] = @image.get_pixels[width][height][1]
      blue[i][j] = @image.get_pixels[width][height][2]
    end
end
return red, green, blue
end

很久以前我用C ++创建了非常类似的用于处理图像的项目,所以我知道做了什么但不确定如何在Ruby中做到正确,因为我是新手

1 个答案:

答案 0 :(得分:1)

您遇到的问题源于Ruby没有“多维数组”的概念,单个数组总是一维的

但是,您可以使用嵌套数组,这些数组是包含数组的数组,例如[[], [], []]

让我们来看看两个特定的地方:

red = Array.new # Note: this could as well be `red = []`

所以你已经为red分配了一个空数组。好的。以下是您稍后的操作:

red[i][j] = ...

我们甚至不需要其余部分,它已经明显破碎了。

在第一次迭代中,red仍然是一个空数组。因此,red[i]nil,因为内部绝对没有。 nil没有数组访问器([][]=),因此您尝试读取或写入数据时会遇到错误,就好像它是一个数组一样。

因此,您需要red[i] 一个实际的数组,以便您可以将数据放入其中。让我们实现它。

由于您事先知道了数组的大小,因此您可以立即使用适当长度的数组分配和填充red

red = Array.new(width) { Array.new(height) }

例如,对于width = 2height = 3,这是您得到的结果:

[
  [nil, nil, nil],
  [nil, nil, nil]
]

现在您已经分配了所需的所有单元格,您可以开始使用有意义的内容覆盖nil

有关构建数组的各种方法,请参阅the docs for Array.new

小心:

出于某种原因,我使用了Array.new的“块状”形式。

初学者经常会错误地使用单个值来填充数组:

red = Array.new(width, Array.new(height))

虽然此表单有其用途,但它不会产生您需要的效果:red中的所有条目都将引用同一个数组,因此修改任何单个行看起来好像都被修改了。

附注:您可能希望在维度中交换widthheight,因为在图形程序中通常会处理的数组,而不是列。但是取决于。可能对您的特定问题没有任何影响。