在数组 Ruby 中保存像素颜色
Saving pixel color in array Ruby
我使用 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 中正确执行,因为我是新手
您遇到的问题源于Ruby没有"multidimensional arrays"的概念,单个数组总是一维的.
但是,您可以 嵌套 数组,这些数组包含数组,例如 [[], [], []]
.
让我们来看看两个特定的地方:
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 = 2
和 height = 3
,您将得到以下结果:
[
[nil, nil, nil],
[nil, nil, nil]
]
现在您已经分配了所有需要的单元格,您可以开始用有意义的东西覆盖 nil
s。
有关构造数组的各种方法,请参阅 the docs for Array.new
。
注意:
出于某种原因,我使用了 Array.new
的 "blocky" 形式。
初学者经常错误地使用单个值来填充数组,如下所示:
red = Array.new(width, Array.new(height))
虽然这种形式有其用途,但它不会产生您需要的效果:red
中的所有条目都将引用 同一个数组 ,因此修改任何一行看起来都好像修改了所有行。
旁注:您可能想交换 width
和 height
的维度,因为在图形程序中通常处理 行 的数组,而不是列.不过要看情况。可能对您的特定问题没有任何影响。
我使用 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 中正确执行,因为我是新手
您遇到的问题源于Ruby没有"multidimensional arrays"的概念,单个数组总是一维的.
但是,您可以 嵌套 数组,这些数组包含数组,例如 [[], [], []]
.
让我们来看看两个特定的地方:
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 = 2
和 height = 3
,您将得到以下结果:
[
[nil, nil, nil],
[nil, nil, nil]
]
现在您已经分配了所有需要的单元格,您可以开始用有意义的东西覆盖 nil
s。
有关构造数组的各种方法,请参阅 the docs for Array.new
。
注意:
出于某种原因,我使用了 Array.new
的 "blocky" 形式。
初学者经常错误地使用单个值来填充数组,如下所示:
red = Array.new(width, Array.new(height))
虽然这种形式有其用途,但它不会产生您需要的效果:red
中的所有条目都将引用 同一个数组 ,因此修改任何一行看起来都好像修改了所有行。
旁注:您可能想交换 width
和 height
的维度,因为在图形程序中通常处理 行 的数组,而不是列.不过要看情况。可能对您的特定问题没有任何影响。