Сохранение цвета пикселя в массиве Ruby - PullRequest
0 голосов
/ 02 мая 2018

Я использую 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 голосов
/ 02 мая 2018

Проблема, с которой вы сталкиваетесь, связана с тем, что в 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 = 2 и height = 3 вот результат, который вы получите:

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

Итак, теперь, когда вы выделили все необходимые ячейки, вы можете начать перезаписывать nil с чем-то значимым.

См. документы по Array.new для различных способов создания массива.


Осторожно:

Я использовал «блочную» форму Array.new по причине.

Начинающие часто допускают ошибку, используя одно значение для заполнения массива следующим образом:

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

Хотя эта форма имеет свое применение, она не даст нужного вам эффекта: все записи в red будут ссылаться на один и тот же массив , поэтому изменение любой отдельной строки будет выглядеть как будто все они изменены.


Примечание: вы, вероятно, захотите поменять размеры width и height, поскольку в графических программах обычно работают с массивами строк , а не столбцами. Зависит, хотя. Может не повлиять на вашу конкретную проблему.

...