【问题标题】:Carrierwave: Extract image from uploaded file and discard original fileCarrierwave:从上传的文件中提取图像并丢弃原始文件
【发布时间】:2012-11-08 18:11:34
【问题描述】:

我们正在使用 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,而不是存储我处理的原始文件?

【问题讨论】:

    标签: ruby-on-rails-3 carrierwave


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

      据我所知,除了手动提取之外,您还可以使用该处理器而不使用版本。

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

      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 文档。

      【讨论】:

      • 感谢您的回复卡米尔。看起来我可以像你说的那样上传文件,但我不确定如何告诉 CarrierWave 存储我从 DICOM 创建的 JPEG。知道是否可以做到吗?
      • 据我所知,您只需将文件替换为 JPEG(在 CW 中,甚至在磁盘上?)。您可能必须覆盖一些默认值,例如更改文件名以匹配 jpeg 扩展名。它实际上只是在文件上传时执行 process 中指定的函数。
      • 非常感谢您的帮助!我仍然有一些奇怪的行为。尽管这似乎可以处理覆盖旧文件,但它永远不会从临时文件夹移动到正确的上传文件夹。一条记录插入到数据库中,但在我的uploads 目录中没有创建文件夹。
      猜你喜欢
      • 2013-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多