0

由于 Paperclip 弃用,我从 Paperclip 切换到 Shrine。

在我的模型Profilepic.rb文件中,我曾经检索图像变体的尺寸,如下所示:

before_create  :save_ratio    

def save_ratio
    geo = Paperclip::Geometry.from_file(image.queued_for_write[:original])
    self.ratio = geo.width / geo.height
  end

基本上我正在保存图像的垂直比例。

它与 Paperclip 配合得很好:我在保存值之前抓取了临时图像queued_for_write并检查了尺寸。Paperclip::Geometry

在 Shrine 中,我向上传者添加了以下内容:

plugin :add_metadata
plugin :store_dimensions

它工作得很好,因为我拥有所有可用信息并且图像已正确上传到 S3。

然而我保存图像比例的新方法不再有效:

after_create  :save_ratio
def save_ratio
    self.ratio = self.image[:original].width.to_i / self.image[:original].height.to_i
  end

我明白了

ProfilepicUploader::UploadedFile:0x00007f69a685c750> 的错误未定义方法“[]”

而在控制台中,创建图像后:

Profilepic.first.image[:original].width.to_i

确实返回正确的值。

编辑

我的上传者:

require "image_processing/mini_magick"

class ProfilepicUploader < Shrine
    include ImageProcessing::MiniMagick
    plugin :processing
    plugin :validation_helpers # to validate image data
    plugin :versions
    plugin :add_metadata
    plugin :store_dimensions

    Attacher.validate do
        validate_max_size 5.megabyte
        validate_mime_type_inclusion ['image/jpg', 'image/jpeg', 'image/png']
    end

    process(:store) do |io, context|
        versions = { original: io } # retain original

        io.download do |original|
            pipeline = ImageProcessing::MiniMagick.source(original)

            versions[:editable]  = pipeline.resize_to_fit!(700, 700)
            versions[:thumbnail] = pipeline.resize_to_fill!(400, 400)
            versions[:small]  = pipeline.resize_to_fill!(200, 200)
        end

        versions # return the hash of processed files
    end

end

我的模型:

class Profilepic < ApplicationRecord
  require "image_processing/mini_magick"
  belongs_to :professionnel
  before_create :set_hashid

  include ProfilepicUploader::Attachment.new(:image) # adds an `image` virtual attribute
  include ProfilepicFinalUploader::Attachment.new(:final_image) # adds an `image` virtual attribute


 attr_accessor :crop_x, :crop_y, :crop_w, :crop_h   

 after_create  :save_ratio_image   

private

  def save_ratio
    self.ratio = self.image[:original].width.to_i / self.image[:original].height.to_i
  end

end
4

2 回答 2

2

Shrine 首先将记录与缓存文件一起保存,然后再次与存储的处理文件一起保存。您收到错误的原因是因为您的代码首先在分配缓存文件时运行,此时尚未完成任何处理,并且self.image是单个上传文件(不是上传文件的哈希)。

您可能想要的是已经从缓存文件中提取比率(这是与后处理相同的上传文件:original):

def save_ratio
  if image_data_changed? && image_attacher.cached?
    self.ratio = image.width.to_f / image.height.to_f
  end
end

或者,您可以创建列image_width并让 Shrine 使用&元数据image_height自动填充它们,然后稍后在 SQL 中计算配给。widthheight

class ProfilepicUploader < Shrine
  plugin :metadata_attributes, width: :width, height: height
end

正如其他答案的评论中提到的,您还可以使用 JSONB 列作为附件列,它也允许您使用 SQL获取width&元数据。height

于 2019-02-26T08:39:58.723 回答
1

我的 2 美分:

如果您使用 Shrine::Attach.promote 在后台处理文件,通过作业或工作人员,versions元数据可能在那时(after_create 回调时间)不可用。

我不确定解决此问题的最佳方法是什么,但您可以通过上下文访问处于处理阶段的模型(https://github.com/shrinerb/shrine/blob/v2.16.0/doc/processing.md#上传处理):

class SomeUploader < Shrine
  process(:store) do |io, context|
    ratio = io.metadata["width"] / io.metadata["height"]
    model = context[:record]
    model.update(ratio: ratio)

    versions = { original: io } # retain original
    io.download do |original|
      pipeline = ImageProcessing::MiniMagick.source(original)
      versions[:small]  = pipeline.resize_to_limit!(300, 300)
      # ....
    end
    versions
  end
end
于 2019-02-25T18:40:48.837 回答