将数组转换为Magick :: Ruby中的图像

时间:2013-08-01 18:54:37

标签: ruby rmagick narray

有没有一种有效的方法从2D NArray(一个应该比常规数组更有效的Ruby类)中的数据创建一个RMagick图像,或者这两个库在它们的数据类型中是不兼容的?

以下代码可行,但它的工作方式很难:使用嵌套的do循环逐个像素地转换数据类型。据我所知,这给了我很多额外的工作,没有NArray的优点。它在1月份的运行速度比糖蜜慢:

  def LineaProcessor.createImage(dataArray, width, height, filename)

    image = Magick::Image.new width, height

    # scale pixel values from 0..256*255 (the RMagick pixel uses 16 bits)
    scaling = 65280/dataArray.max

    # set each pixel...I couldn't find any easy way to convert array types
    width.times do |x|
        height.times do |y|
            g = dataArray[x+y*width]*scaling
            pixel = Magick::Pixel.new(g, g, g,0)
            image.pixel_color x, y, pixel 
      end
    end

    image
  end  

2 个答案:

答案 0 :(得分:0)

以下是我以前用于灰度的一些代码,看起来相对较快:

module Convert
  PX_SCALE = ( 2 ** Magick::QuantumDepth  ).to_f

  # Converts 2D NArray of floats 0.0->1.0 to Magick::Image greyscale (16-bit depth)
  def self.narray_to_image na
    raise( ArgumentError, "Input should be NArray, but it is a #{na.class}") unless na.is_a?(NArray)
    raise( ArgumentError, "Input should have 2 dimensions, but it has #{na.dim}" ) unless na.dim == 2
    width, height = na.shape
    img = Magick::Image.new( width, height ) { self.depth = 16; self.colorspace = Magick::GRAYColorspace }
    img.import_pixels(0, 0, width, height, 'I', na.flatten, Magick::DoublePixel )
    img
  end

  # Converts Magick::Image greyscale to 2D NArray of floats 0.0 -> 1.0
  def self.image_to_narray img
    width = img.columns
    height = img.rows
    pixels = NArray.cast( img.export_pixels( 0, 0, width, height, 'I' ).map { |x| x/PX_SCALE } )
    pixels.reshape( width, height )
  end
end

要阅读的关键方法是Magick::Image#import_pixelsMagick::Image#export_pixelsNArray.cast

应该可以通过逐个通道来处理彩色图像。没有根本原因你必须使用浮点数,我只是希望格式符合我的目的(输入到神经网络)

答案 1 :(得分:0)

您可以将灰度8位NArray转换为像此一样的RMagick图像

require 'narray'
require 'RMagick'
class NArray
  def to_magick
    retval = Magick::Image.new(*shape) { self.depth = 8 }
    retval.import_pixels 0, 0, *shape, 'I', to_s, Magick::CharPixel
    retval
  end
end
sample = NArray.byte(8, 32).indgen.to_magick