使用自定义处理器和裁剪的Paperclip错误

时间:2020-12-29 09:01:06

I have ran into a tricky problem with paperclip and custom processors where I'm loosing some of the styles.

我遇到了一个棘手的问题,关于回形针和自定义处理器,我正在失去一些风格。

I've got a picture which I crop with coordinates passed from the view. Cropping went well and original picture is saved but when running reprocess to make the other styles I get this error:

我有一张从视图中通过的坐标剪切出来的图片。裁剪进行得很好,原始图片保存了下来,但是当重新进行重新处理时,我得到了这个错误:

convert: geometry does not contain image `/var/folders/bg/w2mft0x51t933pzhgpvhm5800000gn/T/paperclip-reprocess20111114-3404-13lp780-0' @ warning/transform.c/CropImage/571.

And when I get this error the original image style is lost.

当我得到这个错误时,原来的图像样式就丢失了。

I tried toying around callbacks and paperclip stuff but with no success. I'm really stuck and can't find any info on the matter.

我试着摆弄回叫和回形针之类的东西,但没有成功。我真的被困住了,在这件事上找不到任何信息。

The example I followed is from http://railscasts.com/episodes/182-cropping-images

我遵循的示例来自http://railscasts.com/des/182 - croppingimages。

What is different from the example in the screencast is that I want to crop the original and then generate thumbnails from it with the standard paperclip styles.

与screencast中的示例不同的是,我想裁剪原始文件,然后用标准的paperclip样式从中生成缩略图。

Here is my code.

这是我的代码。

My processor:

我的处理器:

module Paperclip

  class Cropper < Thumbnail
    def transformation_command
      if crop_command
        original_command = super
        if original_command.include?('-crop')
          original_command.delete_at(super.index('-crop') + 1)
          original_command.delete_at(super.index('-crop'))
        end
        crop_command + original_command
      else
        super
      end
    end

    def crop_command
      target = @attachment.instance
      if target.cropping?
        ["-crop", "#{target.crop_w.to_i}x#{target.crop_h.to_i}+#{target.crop_x.to_i}+#{target.crop_y.to_i}", "+repage"]
      end
    end
  end

end

My model:

我的模型:

class Item < ActiveRecord::Base

  belongs_to :category
  belongs_to :picture

  validates :picture_id,  :presence => true
  validates :category_id, :presence => true

  validates :title_url,   :presence => true, :uniqueness => { :case_sensitive => false }
  validates :title,       :presence => true, :uniqueness => { :case_sensitive => false }
  validates :information, :presence => true, :uniqueness => { :case_sensitive => false }

  validates :crop_x,      :presence => true, :numericality => { :only_integer => true, :greater_than_or_equal_to => 0 }
  validates :crop_y,      :presence => true, :numericality => { :only_integer => true, :greater_than_or_equal_to => 0 }
  validates :crop_w,      :presence => true, :numericality => { :only_integer => true, :greater_than_or_equal_to => 0 }
  validates :crop_h,      :presence => true, :numericality => { :only_integer => true, :greater_than_or_equal_to => 0 }

  Paperclip.interpolates :title_url do |attachment, style|
    attachment.instance.title_url
  end

  has_attached_file :image,
                    :styles => {
                      :small    => { :format => 'jpg', :quality => 100, :geometry => '100x100#' },
                      :medium   => { :format => 'jpg', :quality => 100, :geometry => '200x200#' },
                      :large    => { :format => 'jpg', :quality => 100, :geometry => '300x300#' },
                      :original => { :format => 'jpg', :quality => 100, :geometry => '', :processors => [:cropper] }
                    },
                    :path => ":rails_root/public/attachments/:class/:attachment/:id_partition/:style/:title_url.:extension",
                    :url  =>                   "/attachments/:class/:attachment/:id_partition/:style/:title_url.:extension"

  before_validation   :strip_attributes
  before_save         :image_assign,    :if => :cropping?
  after_create        :image_reprocess, :if => :cropping?

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

  def image_geometry(style = :original)
    @geometry ||= {}
    @geometry[style] ||= Paperclip::Geometry.from_file(avatar.path(style))
  end

  def calc(width,height)
    # original large side / smalled picture large side
    calc_width  = self.picture.width.to_f  / width
    calc_height = self.picture.height.to_f / height
    if calc_width >= calc_height
      return calc_width
    else
      return calc_height
    end
  end

  private

  def image_assign
    self.image = self.picture.image
  end

  def image_reprocess
    image.reprocess!
  end

  def strip_attributes
    # normalize attributes
    self.title.strip!
    self.title_url = Utility::friendly_url(self.title)
    self.information.strip!
  end

end

1 个解决方案

#1


4  

Since I saw that at least one person other than me has bumped into problems I'm sharing my final solution to the problem of custom paperclip processor for cropping. There are some stuff like centering the picture cropping. I'm pretty sure this is far from perfect but it has worked reliably about a year now.

因为我看到除了我之外至少有一个人遇到了问题,所以我将分享我的最终解决方案,关于裁剪的自定义paperclip处理器的问题。有一些东西,比如对照片的裁剪。我很确定这还远远不够完美,但它已经可靠地工作了一年了。

module Paperclip

  class CropperItem < Thumbnail
    def transformation_command
      if crop_command
        original_command = super
        if original_command.include?('-crop')
          original_command.delete_at(super.index('-crop') + 1)
          original_command.delete_at(super.index('-crop'))
        end
        if original_command.include?('-resize')
          crop_command('square') + original_command
        else
          crop_command + original_command
        end
      else
        super
      end
    end

    def crop_command(dimensions = nil)
      target = @attachment.instance
      if target.cropping?
        case dimensions
        when 'square'
          if target.crop_w > target.crop_h
            crop_w = target.crop_w.to_i
            crop_h = target.crop_w.to_i
            crop_x = target.crop_x.to_i
            crop_y = target.crop_y.to_i - ((target.crop_w.to_i-target.crop_h.to_i)/2).to_i
            crop_x = 0 if crop_x < 0
            crop_y = 0 if crop_y < 0
          elsif target.crop_w < target.crop_h
            crop_w = target.crop_h.to_i
            crop_h = target.crop_h.to_i
            crop_x = target.crop_x.to_i - ((target.crop_h.to_i-target.crop_w.to_i)/2).to_i
            crop_y = target.crop_y.to_i
            crop_x = 0 if crop_x < 0
            crop_y = 0 if crop_y < 0
          else
            crop_w = target.crop_w.to_i
            crop_h = target.crop_h.to_i
            crop_x = target.crop_x.to_i
            crop_y = target.crop_y.to_i
          end
          ["-crop", "#{crop_w}x#{crop_h}+#{crop_x}+#{crop_y}", "+repage"]
        else
          ["-crop", "#{target.crop_w.to_i}x#{target.crop_h.to_i}+#{target.crop_x.to_i}+#{target.crop_y.to_i}", "+repage"]
        end
      end
    end
  end

end

And I ended up using something like this in the model.

最后我在模型中使用了类似的东西。

has_attached_file :photo,
                  :styles => {
                    :small        => { :format => 'jpg', :quality => 100, :geometry => '50x50^'   },
                    :thumb_small  => { :format => 'jpg', :quality => 100, :geometry => '110x110^' },
                    :thumb_medium => { :format => 'jpg', :quality => 100, :geometry => '150x150^' },
                    :medium       => { :format => 'jpg', :quality => 100, :geometry => '240x160^' },
                    :banner_small => { :format => 'jpg', :quality => 100, :geometry => '200x120#' },
                    :banner       => { :format => 'jpg', :quality => 100, :geometry => '300x250^' },
                    :focus_crop   => { :format => 'jpg', :quality => 100, :geometry => '400x400>' },
                    :focus_orig   => { :format => 'jpg', :quality => 100, :geometry => '' }
                  },
                  :convert_options => {
                    :thumb_small  => "-gravity Center -extent 50x50",
                    :thumb_small  => "-gravity Center -extent 110x110",
                    :thumb_medium => "-gravity Center -extent 150x150",
                    :medium       => "-gravity Center -extent 240x160",
                    :banner_small => "-gravity Center -extent 200x120",
                    :banner       => "-gravity Center -extent 300x250",
                    :focus_crop   => "-gravity Center"
                  },
                  :processors => [:cropper_item],
                  :path => PAPERCLIP_PATH,
                  :url  => PAPERCLIP_URL

I hope this helps someone.

我希望这能帮助某人。

#1


4  

Since I saw that at least one person other than me has bumped into problems I'm sharing my final solution to the problem of custom paperclip processor for cropping. There are some stuff like centering the picture cropping. I'm pretty sure this is far from perfect but it has worked reliably about a year now.

因为我看到除了我之外至少有一个人遇到了问题,所以我将分享我的最终解决方案,关于裁剪的自定义paperclip处理器的问题。有一些东西,比如对照片的裁剪。我很确定这还远远不够完美,但它已经可靠地工作了一年了。

module Paperclip

  class CropperItem < Thumbnail
    def transformation_command
      if crop_command
        original_command = super
        if original_command.include?('-crop')
          original_command.delete_at(super.index('-crop') + 1)
          original_command.delete_at(super.index('-crop'))
        end
        if original_command.include?('-resize')
          crop_command('square') + original_command
        else
          crop_command + original_command
        end
      else
        super
      end
    end

    def crop_command(dimensions = nil)
      target = @attachment.instance
      if target.cropping?
        case dimensions
        when 'square'
          if target.crop_w > target.crop_h
            crop_w = target.crop_w.to_i
            crop_h = target.crop_w.to_i
            crop_x = target.crop_x.to_i
            crop_y = target.crop_y.to_i - ((target.crop_w.to_i-target.crop_h.to_i)/2).to_i
            crop_x = 0 if crop_x < 0
            crop_y = 0 if crop_y < 0
          elsif target.crop_w < target.crop_h
            crop_w = target.crop_h.to_i
            crop_h = target.crop_h.to_i
            crop_x = target.crop_x.to_i - ((target.crop_h.to_i-target.crop_w.to_i)/2).to_i
            crop_y = target.crop_y.to_i
            crop_x = 0 if crop_x < 0
            crop_y = 0 if crop_y < 0
          else
            crop_w = target.crop_w.to_i
            crop_h = target.crop_h.to_i
            crop_x = target.crop_x.to_i
            crop_y = target.crop_y.to_i
          end
          ["-crop", "#{crop_w}x#{crop_h}+#{crop_x}+#{crop_y}", "+repage"]
        else
          ["-crop", "#{target.crop_w.to_i}x#{target.crop_h.to_i}+#{target.crop_x.to_i}+#{target.crop_y.to_i}", "+repage"]
        end
      end
    end
  end

end

And I ended up using something like this in the model.

最后我在模型中使用了类似的东西。

has_attached_file :photo,
                  :styles => {
                    :small        => { :format => 'jpg', :quality => 100, :geometry => '50x50^'   },
                    :thumb_small  => { :format => 'jpg', :quality => 100, :geometry => '110x110^' },
                    :thumb_medium => { :format => 'jpg', :quality => 100, :geometry => '150x150^' },
                    :medium       => { :format => 'jpg', :quality => 100, :geometry => '240x160^' },
                    :banner_small => { :format => 'jpg', :quality => 100, :geometry => '200x120#' },
                    :banner       => { :format => 'jpg', :quality => 100, :geometry => '300x250^' },
                    :focus_crop   => { :format => 'jpg', :quality => 100, :geometry => '400x400>' },
                    :focus_orig   => { :format => 'jpg', :quality => 100, :geometry => '' }
                  },
                  :convert_options => {
                    :thumb_small  => "-gravity Center -extent 50x50",
                    :thumb_small  => "-gravity Center -extent 110x110",
                    :thumb_medium => "-gravity Center -extent 150x150",
                    :medium       => "-gravity Center -extent 240x160",
                    :banner_small => "-gravity Center -extent 200x120",
                    :banner       => "-gravity Center -extent 300x250",
                    :focus_crop   => "-gravity Center"
                  },
                  :processors => [:cropper_item],
                  :path => PAPERCLIP_PATH,
                  :url  => PAPERCLIP_URL

I hope this helps someone.

我希望这能帮助某人。