Carrierwave:从上传的文件中提取图像并丢弃原始文件

时间:2012-11-08 18:11:34

标签: ruby-on-rails-3 carrierwave

我们正在使用CarrierWave在我正在处理的项目中上传文件。满足了上传DICOM文件需求的新要求​​。 DICOM个文件除了包含大量其他数据外,还包含一个或多个图像。使用Ruby DICOM gem,我可以轻松地从文件中提取图像。当我尝试使用CarrierWave上传它们时,我的问题出现了。

我希望能够从上传的文件中提取JPEG,并存储该文件而不是原始的DICOM文件。我尝试像这样创建version上传的文件:

version :jpeg, :if => :is_dicom? do
  process :create_jpeg
end

def is_dicom?(file)
  IO.binread(file.to_file, 4, OFFSET) == 'DICM'
end

def create_jpeg
  Rails.logger.debug "self is class #{self.class}"
  dcm = DICOM::DObject.read(file.path)
  image = dcm.image.normalize
end

我将create_jpeg方法基于我发现的另一个create_thumbnail方法,在没有异常处理的情况下,将其缩减为:

def create_thumbnail(width, height, gravity = 'Center')
  self.resize_to_fill(width, height, gravity)
end

我可以在调试控制台中看到DICOM正在被成功读取,但它实际上并没有保存将要提取的JPEG。相反,我得到了我的原始DICOM和一个'jpeg'的副本添加到文件名的前面。如何告诉CarrierWave我要存储我提取的JPEG,而不是存储我处理的原始文件?

2 个答案:

答案 0 :(得分:0)

据我所知,只需创建一个不同版本的文件,以便以后恢复。为防止这种情况,您必须使用JPEG覆盖文件。

如何在模型中创建虚拟属性image_dicom,提取JPEG,然后将其分配给image附加的上传者?现在可以解析上传具有image_dicom属性名称的文件,但不会将其存储在数据库中。

你必须解析上传的文件,这是Carrierwave自动执行的操作,但我认为这不是一个大问题。不确定它是如何在内部表示的,我知道它不是常规File对象,但不应该难以检测和提取原始数据和JPEG。

编辑:显然,如果你需要解析DICOM文件和常规图像,这会变得有点复杂,因为你必须检测文件类型并采取相应的行动。

答案 1 :(得分:0)

除了手动提取,你也可以在不使用版本的情况下使用该处理器。

这样,您可以在上传文件时自行操作,而无需创建版本。我从来没有这样做过,但它似乎就像在做一样简单:

process :create_jpeg, :if => :is_dicom?

def is_dicom?(file)
  IO.binread(file.to_file, 4, OFFSET) == 'DICM'
end

def create_jpeg(image)
  directory = File.dirname(current_path)

  # not quite thread safe, generate something unique here
  tmpfile   = File.join(directory, "tmpfile")

  FileUtils.mv(current_path, tmpfile)

  dcm = DICOM::DObject.read(tmpfile)
  image = dcm.image.normalize.write(current_path)

  FileUtils.rm(tmpfile)
end

# replace the extension with jpg
def filename
  super.chomp(File.extname(super)) + '.jpg'
end

复制并改编自:http://www.freezzo.com/2010/12/23/create-ffmpeg-processor-for-carrierwave-in-rails-3/和Carrierwave文档。