使用fastimage获取通过carrierwave上传的图像的实际尺寸

Get actual dimensions of image uploaded with carrierwave using fastimage

我正在尝试使用载波获取图像的尺寸,但我希望使用我自己创建的代码来获取尺寸,我试图 运行 fastimage after_saveafter commit .我收到此错误:

wrong number of arguments (1 for 0)
  Extracted source (around line #45): 
  # [String] contents of the file
  #
  def read
    file.read if file.respond_to?(:read)
  end

carrierwave (0.11.2) lib/carrierwave/uploader/proxy.rb:45:in `read'
fastimage (2.1.0) lib/fastimage.rb:343:in `block in fetch_using_read'

模型看起来像这样

class Micropost < ApplicationRecord

  after_save :change_picture_dimensions
  mount_uploader :picture, PictureUploader

 def change_picture_dimensions
  if :picture?
    widthheight = FastImage.size(picture)
    if widthheight[0] >= 501
      newheightratio =  widthheight[1].to_f / widthheight[0].to_f
  newheight = newheightratio * 500
      self.picture = "<img src=\"" + picture.to_s + "\" width=\"500\" height=\"" +  newheight.to_s + "\">"
      else
      self.picture = "<img src=\"" + picture.to_s + "\" width=\"" + widthheight[0].to_s + "\" height=\"" + widthheight[1].to_s + "\">"
      end
    end
  end

这只是我系统上的一个本地文件。我可以使用 minimagick here 获取尺寸,但想了解更多关于载波过程的信息,以及为什么我不能使用我的方法获取导致此错误的尺寸?在我的方法中,我只是使用一个比率来保持纵横比,但适合任何图像的 div 的固定宽度。

编辑:我意识到我需要在保存对象之前完成它,但即使使用 before_create 我也会遇到同样的错误。

您不能为图片分配字符串。它必须是 URL、文件或 IO 对象。

如果您想预处理图像宽度以适应 500px,只需声明以下内容:

# app/uploaders/picture_uploader.rb
class PictureUploader < CarrierWave::Uploader::Base
   ...
   process resize_to_fit: [500, nil]
end

class Micropost < ApplicationRecord
  mount_uploader :picture, PictureUploader
end

要从其他服务器保存图像,您可以执行以下操作:

micropost = Micropost.create(
  picture: 'http://server.example.org/image.png'
)

现在您可以在页面上呈现它了

= image_tag micropost.picture.url

您还可以在模型中存储图像大小。阅读 this documentation 如何执行此操作。将图像尺寸保存到图片模型后,可以在 image_tag 中指定它们,但我认为这是多余的,因为浏览器会自动检测图像尺寸

= image_tag micropost.picture.url, width: picture.width, height: picture.height