使用CarrierWave和MiniMagick将Rails裁剪并上传到S3

时间:2012-05-28 23:47:49

标签: ruby-on-rails carrierwave

我已经在这一段时间了。使用这个RailsCast我已经能够修改它以使用CarrierWave - 至少在理论上是这样。我试图允许用户裁剪他们的个人资料照片,然后使用CarrierWave将其上传到S3。到目前为止,这是有效的:

  • 用户上传图片及其余的个人资料信息
  • 他们成功进入裁剪页面,裁剪照片 - 上传照片并成功拍摄原始图像尺寸
  • 点击“裁剪”以保存图像不会触发任何错误(模型保存得很好),但实际上并没有裁剪或重新创建版本。

所以,这是我得到的代码。这是模型:

attr_accessor :crop_x, :crop_y, :crop_w, :crop_h, :original_width, :original_height
attr_accessible :avatar, :remove_avatar
after_update :reprocess_avatar, :if => :cropping?

mount_uploader :avatar, ProfileBaseUploader

def cropping?
  !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
end

private
  def reprocess_avatar
    avatar.process!
    avatar.recreate_versions!
  end

漂亮的锅炉板 - crop_x等属性是从裁剪视图中分配的。我已经确认这些正在传入并正确分配,并且调用了reprocess_avatar方法。

以下是我的上传代码:

include CarrierWave::MiniMagick
include CarrierWaveDirect::Uploader

storage :fog

require 'guid'

process :cropper
process :store_best_geometry

version :tiny_thumb do
  process :resize_to_limit => [50, 50]
end

version :thumb do
  process :resize_to_limit => [200, 200]
end

version :large do
  process :resize_to_fit => [500, 500]
end

def extension_white_list
    %w(jpg jpeg gif png)
end

def filename
   @name ||= "#{secure_token}.#{file.extension}" if original_filename.present?
end

def store_best_geometry
  manipulate! do |img|
    if model
      model.original_width = img['width']
      model.original_height = img['height']
    end
    img = yield(img) if block_given?
    img
  end
end

def cropper
  return unless model.cropping?
  manipulate! do |img|
    img = img.crop("#{model.crop_x}x#{model.crop_y}+#{model.crop_w}+#{model.crop_h}")
    img
  end
end

protected
  def secure_token
    var = :"@#{mounted_as}_secure_token"
    model.instance_variable_get(var) or model.instance_variable_set(var, Guid.new)
  end

认为那个过程!和recreate_versions!方法根本无法正常运行,但我不知道为什么。我没有任何可以提供的错误(如果有人知道如何生成一个我很乐意这样做)。我知道store_best_geometry方法工作得很好。对于裁剪来说,不能说同样的事情。

有什么想法吗?

1 个答案:

答案 0 :(得分:9)

就像一次糟糕的飞机失事一样,我做错了很多事情。

首先,我有错误顺序的裁剪论据。在我的问题中,你会注意到我:

img.crop('[x offset]x[y offset]+[width]+[height]')

正确的顺序是:

img.crop('[width]x[height]+[x offset]+[y offset]')

这就是问题所在。试图以错误的顺序执行此操作会抛出一个错误(挖到控制台中找到它)关于提供的几何图形无效。

下一个问题:使用我的cropper方法破坏yield链并返回STRING而不是IMAGE。事实证明,crop方法返回一个字符串。看看原始的cropper方法:

def cropper
  return unless model.cropping?
  manipulate! do |img|
    img = img.crop("#{model.crop_x}x#{model.crop_y}+#{model.crop_w}+#{model.crop_h}")
    img
  end
end

糟糕!返回的最后一件事是一个字符串。事实证明,正确的方法是直接在图像上调用方法:

def cropper
  return unless model.cropping?
  manipulate! do |img|
    img.crop("#{model.crop_w}x#{model.crop_h}+#{model.crop_x}+#{model.crop_y}")
    img = yield(img) if block_given?
    img
  end
end

最后我做错了 - 这是一个完整的业余时间错误 - 没有使一些关键属性可访问。在我的无限智慧中,我假设attr_accessor会使属性可访问。不。我必须修改我的模型才能访问crop_x,crop_y,crop_w和crop_h参数。

attr_accessor :crop_x, :crop_y, :crop_w, :crop_h, :original_width, :original_height
attr_accessible :avatar, :remove_avatar, :crop_x, :crop_y, :crop_w, :crop_h
after_update :reprocess_avatar, :if => :cropping?

最后一点,不重要但要方便。我不需要打电话过程! as recreate_versions!这样做对我来说。

希望这对至少有一个人有帮助。