Carrierwave和Jcrop,裁剪后删除原始文件?

Carrierwave and Jcrop, delete original after crop?

制作裁剪后的版本后,我很难让 Carrierwave 删除原始文件。我正在制作一个 600 像素的上传版本供用户裁剪,但在裁剪后我希望该版本被删除,因为它从未在网站上使用过。

我尝试了网上找到的几种解决方案,但它们都在裁剪之前删除了大版本,而不是裁剪之后。

这是我的 Carrierwave 上传器:

# encoding: utf-8

class AvatarUploader < CarrierWave::Uploader::Base

  include CarrierWave::RMagick

  storage :file
  # storage :fog

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  # Only allows jpg, jpeg, or png
  def extension_white_list
    %w(jpg jpeg png)
  end

  resize_to_limit(600, 600)

  version :profile do
    process :crop
    resize_to_fill(120, 120)
    def full_filename (for_file = model.file) 
      "profile.png" 
    end
  end

  version :timeline do
    process :crop
    resize_to_fill(50, 50)
    def full_filename (for_file = model.file) 
      "timeline.png" 
    end
  end

  version :navigation do
    process :crop
    resize_to_fill(20, 20)
    def full_filename (for_file = model.file) 
      "navigation.png" 
    end
  end

  def crop
    if model.crop_x.present?
      resize_to_limit(600, 600)
      manipulate! do |img|
        x = model.crop_x.to_i
        y = model.crop_y.to_i
        w = model.crop_w.to_i
        h = model.crop_h.to_i
        img.crop!(x, y, w, h)
      end
    end
  end

end

您可以使用 after_store 回调删除原始文件(使用 File.delete),或者您可以修改原始文件,使其成为您需要的最大尺寸:

version :normal do
   process :resize_to_limit => [600,600]
end

对于那些试图解决在图像名称中添加一些修订信息(例如裁剪)的问题的人,我找到了一种方法。

# :large is the cropped version
version :small_square, from_version: :large do 
  before :cache, :reset_revision
  after :store, :remove_old_revision

  def full_filename(for_file)
    fname = super(for_file)
    "#{ fname.pathmap('%n') }_#{ model.image_revision }#{ fname.pathmap('%x') }"
  end

  def full_original_filename
    "#{ super.pathmap('%n') }_#{ model.image_revision }#{ super.pathmap('%x') }"
  end

  def remove_old_revision(file = nil)
    File.delete(@old_path) if @old_path && File.exists?(@old_path)
  end

  def reset_revision(file = nil)
    # Otherwise we'll get `cannot update new record` error
    if model.persisted?
      # Creating an instance variable that will be used after storing the cropped version
      @old_path = File.join(Rails.public_path, model.public_send(mounted_as).store_dir, full_original_filename)

      # I use :image_revision column in the DB
      model.update_columns(image_revision: SecureRandom::hex(8))
    else
      model.image_revision = SecureRandom::hex(8)
    end
  end

  process :crop_small_square
end

因此,在更改生成的图像名称然后删除第一个版本之前,它存储裁剪版本的第一个版本的路径。

我花了一些时间找出将一些咒语附加到文件的特定版本末尾的方法:它采取更新操作,而不仅仅是分配属性。 Carrierwave 的文档不是那么准确。