ActiveStorage-上传后获取图像尺寸

问题描述 投票:0回答:2

我正在使用Rails + ActiveStorage上载图像文件,并希望在上载后在数据库中保存宽度和高度。但是,我在任何地方都找不到此类示例。

这是我从各种API文档中整理而来的,但最终出现此错误:private method 'open' called for #<String:0x00007f9480610118>。将blob替换为image.file会导致Rails记录“由于ImageMagick不支持文件而跳过了图像分析”(https://github.com/rails/rails/blob/master/activestorage/lib/active_storage/analyzer/image_analyzer.rb#L39)。

代码:

class Image < ApplicationRecord
  after_commit { |image| set_dimensions image }

  has_one_attached :file

  def set_dimensions(image)
    if (image.file.attached?)
      blob = image.file.download

      # error: private method `open' called for #<String:0x00007f9480610118>
      meta = ActiveStorage::Analyzer::ImageAnalyzer.new(blob).metadata
    end
  end
end

此方法也有问题,因为在销毁时也会调用after_commit

TLDR:是否有“适当”的方式在上传后立即获取图像元数据?

ruby-on-rails rails-activestorage
2个回答
0
投票

我认为您可以在更新之前从javascript获取尺寸,然后将这些数据发布到控制器中。您可以查看一下:Check image width and height before upload with Javascript


0
投票

回答自己的问题:我原来的解决方案已经结束,但是需要安装ImageMagick(不是,并且错误消息没有指出)。这是我的最终代码:

class Image < ApplicationRecord
  attr_accessor :skip_set_dimensions
  after_commit ({unless: :skip_set_dimensions}) { |image| set_dimensions image }

  has_one_attached :file

  def set_dimensions(image)
    if (Image.exists?(image.id))
      if (image.file.attached?)
        meta = ActiveStorage::Analyzer::ImageAnalyzer.new(image.file).metadata

        image.width = meta[:width]
        image.height = meta[:height]
      else
        image.width = 0
        image.height = 0
      end

      image.skip_set_dimensions = true
      image.save!
    end
  end
end

我还使用this technique跳过了save!上的回调,从而防止了无限循环。

© www.soinside.com 2019 - 2024. All rights reserved.