Paperclip sharpening processor causes resizing styles not to work - ruby-on-rails

I'm trying to sharpen images uploaded through paperclip. The sharpen code is working but it causes the styles to not work. The code is like this:
has_attached_file :photo,
:styles => {
:thumb => {:geometry => "100x100>"},
:medium => {:geometry => "300x300>"},
:original => {:geometry => "1024x1024>"}
},
:processors => [:sharpen],
:storage => :s3,
:s3_credentials => "#{Rails.root}/config/s3.yml",
:path => "/:style/:id/:filename"
Now if I remove the processors option, the uploaded images are resized as specified. However if I include the processors option, all the resulting images are of original size.
My sharpen processor looks like this:
module Paperclip
class Sharpen < Paperclip::Processor
def initialize file, options = {}, attachment = nil
super
#file = file
#current_format = File.extname(#file.path)
#basename = File.basename(#file.path, #current_format)
end
def make
dst = Tempfile.new(#basename)
dst.binmode
command = "#{File.expand_path(#file.path)} -unsharp 1.5×1.0+1.5+0.02 #{File.expand_path(dst.path)}"
begin
success = Paperclip.run("convert", command)
rescue PaperclipCommandLineError
raise PaperclipError, "There was an error converting sharpening the image for #{#basename}"
end
dst
end
end
end
Any thoughts?

Try adding :thumbnail to processors list:
:processors => [:thumbnail, :sharpen]
By default :thumbnail is there but now you are overriding that setting.
"Multiple processors can be specified, and they will be invoked in the order they are defined in the :processors array. Each successive processor will be given the result of the previous processor's execution. All processors will receive the same parameters, which are what you define in the :styles hash."
https://github.com/thoughtbot/paperclip

Related

Paperclip post processing conversion does not update file_name, content_type attributes

I would like to restrict File uploads to images only, and convert them automatically to .png. To do so, I use this class:
class ImageAttachment < ActiveRecord::Base
attr_accessible :file, :file_file_name, :file_content_type, :file_file_size
validates_attachment :file,
:content_type => { :content_type => ["image/jpg", "image/tiff", "image/png"] }
has_attached_file :file,
:styles => { :original => ["100%", :png],
:large => ["500x500", :png],
:medium => ["150x150", :png],
:thumb => ["75x100", :png]
},
:default_url => "/system/missing_thumb.png"
end
As I understand, the :styles => { :original => ["100%", :png], ...} should convert all uploaded files that pass validation to .png files. Therefore, I expect the following things to happen when uploading a file example.tiff:
convert the file to .png
change the file name accordingly to example.png
change the content type accordingly to "image/png"
Here's a spec I use:
it "should convert all image types to .png" do
test_file = File.new(Rails.root + "spec/fixtures/images/test.tiff")
attachment = ImageAttachment.create :file => test_file
attachment.file.url.should == "some/paperclip/path/.../test.png"
attachment.file_file_name.should == "test.png"
attachment.file_content_type.should == "image/png"
end
The first assertion is true, and I can also see ImageMagick output in the terminal,
but attachment.file_file_name still returns example.tiff, and attachment.file_content_type returns "image/tiff".
Is my assumption that paperclip automatically updates the file_file_name and the file_content_type attributes wrong?
If so, how would I best do this on my own?

Rails paperclip generate thumbnail from other style

I'm following the jcrop rails tutorial, but I've hit a snag. What it comes down to is the fact that paperclip is generating the thumbnail from the original file, but I need it to be generated from another style. The original file doesn't have any space between the product shot and the edge of the document. Therefore I can't crop further out. To combat that, I made another style which has white pixel padding. That's what I want to generate the thumbnail from.
# croppable is the one with the padding...it's what shows up in the crop view.
# I want :thumb to be generated from THAT style, not :original.
# When generating from :original, the crop offset/size is screwed because the dimensions of :original don't match :cropped
# and I can't crop beyond the pixel dimensions of :original.
has_attached_file :photo, :styles => {
:thumb => { :geometry => "300x300#", :format => :jpg, :processors => [:cropper] },
:general => ["150x375", :jpg],
:show => ["x425", :jpg],
:croppable => ["1200x1200>", :jpg]
},
:url => "/assets/wines/:style/:wine_name",
:path => ":rails_root/public:url",
:default_url => ":wine_default",
:default_path => ":rails_root/public:wine_default",
:default_style => :show,
:convert_options => {
:thumb => '-gravity center -rotate -30',
:croppable => '-gravity center -extent 1200x1200',
:general => '-gravity center -extent 150x375 -quality 95',
:all => '-quality 100 -antialias -flatten -background white -unsharp 0.3x0.3+5+0'
},
:processors => [:thumbnail, :compression]
I came across a processor that someone else had made online and used it for myself. Details can be found at http://pjkh.com/articles/speeding-up-thumbnail-generation-with-paperclip/ for advanced usage information.
recursive_thumbnail.rb (include in lib/paperclip_processors)
module Paperclip
class RecursiveThumbnail < Thumbnail
def initialize file, options = {}, attachment = nil
super Paperclip.io_adapters.for(attachment.styles[options[:thumbnail] || :original]), options, attachment
end
end
end
and for your model:
:styles => {
:croppable => ["1200x1200>", :jpg],
:show => ["x425", :jpg],
:general => ["150x375", :jpg],
:thumb => {
:geometry => "150x150^",
:format => :jpg,
:processors => [:recursive_thumbnail] },
:thumbnail => :croppable
}
Maybe this would help you or someone else like me who Google led to this question.
https://github.com/thoughtbot/paperclip/wiki/Thumbnail-Generation
Generating/regenerating your thumbnails
Note: regenerating only one of several defined styles as described in
some of the examples below will lead to broken paths/urls for all
other styles if you have :hash in your paperclip_defaults[:path] and
:updated_at in your paperclip_defaults[:hash_data] (and you have by
default). Don’t do this unless you really know what you’re doing.
You can (re)generate your thumbnails en masse with Paperclip’s rake
tasks. Using our example class above:
bundle exec rake paperclip:refresh:thumbnails CLASS=User

How do I get Paperclip to recognize custom processors instead of just pushing styles through to thumbnail?

I am not having any problem getting the custom processor to load, however when I try to call it from has_attached_file, paperclip ignores it, and instead just runs thumbnail.
model
has_attached_file :file,
:styles => { :web => "some input" },
:processors => [ :custom ],
:url => ":class/:id/:style/:basename.:extension",
:path => ":class/:id/:style/:basename.:extension"
:storage => :s3
As simple a processor as can be made just to show that the processor has been run
processor.rb
module Paperclip
class Custom < Processor
attr_accessor :input
def initialize(file, options = {}, attachment = nil)
super
#basename = File.basename(file.path, File.extname(file.path))
end
def make
dst = Tempfile.new([ #basename, 'jpg' ].compact.join("."))
dst
end
end
end
But instead when I check the saved record it returns instance variables from thumbnail
>record.file.styles
{:web=>
#<Paperclip::Style:0x00000102f185d0
#attachment=
http://s3.amazonaws.com/bucket/model/id/base_name/file_name.jpg,
#format=nil,
#geometry="some_input",
#name=:web,
#other_args={}>}
I must be missing something in either writing the processor or calling it. Any idea what is going on here?
Have you tried something like this?
has_attached_file :file,
:styles => {
:my_super_style => {:geometry => "100x100#", :foo => "bar", :processors => [:custom]}
},
Have you put in the right place?
lib/paperclip_processors/custom.rb
:styles => { :web => "some input" },
:processors => [ :custom ],
should be:
:styles => {
:web => {:geometry => "some input", :processors => [:custom]},

Rails Paperclip how to use filter options of ImageMagick?

I recently implemented Paperclip with Rails and want to try out some of the filter options from ImageMagick such as blur. I've not been able to find any examples of how to do this. Does it get passed through :style as another option?
:styles => { :medium => "300x300#", :thumb => "100x100#" }
#plang's answer was correct but I wanted to give the exact solution to the blur, just in case someone was looking and found this question:
:convert_options => { :all => "-blur 0x8" }
// -blur {radius}x{sigma}
Which changed this:
To this:
I did not test this, but you should be able to use the "convert_options" parameter, like this:
:convert_options => { :all => ‘-colorspace Gray’ }
Have a look at https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/thumbnail.rb
I personnaly use my own processor.
In Model:
has_attached_file :logo,
:url => PaperclipAssetsController.config_url,
:path => PaperclipAssetsController.config_path,
:styles => {
:grayscale => { :processors => [:grayscale] }
}
In lib:
module Paperclip
# Handles grayscale conversion of images that are uploaded.
class Grayscale < Processor
def initialize file, options = {}, attachment = nil
super
#format = File.extname(#file.path)
#basename = File.basename(#file.path, #format)
end
def make
src = #file
dst = Tempfile.new([#basename, #format])
dst.binmode
begin
parameters = []
parameters << ":source"
parameters << "-colorspace Gray"
parameters << ":dest"
parameters = parameters.flatten.compact.join(" ").strip.squeeze(" ")
success = Paperclip.run("convert", parameters, :source => "#{File.expand_path(src.path)}[0]", :dest => File.expand_path(dst.path))
rescue PaperclipCommandLineError => e
raise PaperclipError, "There was an error during the grayscale conversion for #{#basename}" if #whiny
end
dst
end
end
end
This might not be 100% necessary for a simple grayscale conversion, but it works!
Rails 5, Paperclip 5 update
Instead of having to add a library now, you can just call out to ImageMagick's convert command on the system to use its grayscale option. You can do the same for blur or any of the other ImageMagick options, but I needed to do this for conversion to grayscale.
In your model (client that has a logo):
class Client < ApplicationRecord
has_attached_file :logo,
styles: { thumb: "243x243#", grayscale: "243x243#" }
# ensure it's an image
validates_attachment_content_type :logo, content_type: /\Aimage\/.*\z/
# optional, just for name and url to be required
validates :name, presence: true
validates :url, presence: true
after_save :convert_grayscale
def convert_grayscale
system "convert #{self.logo.path(:thumb)} -grayscale Rec709Luminance #{self.logo.path(:grayscale)}"
end
def logo_attached?
self.logo.file?
end
end
Then just use in the view like this (per Paperclips github docs).
In your view:
<%= image_tag(client.logo.url(:grayscale), class: 'thumbnail', alt: client.name, title: client.name) %>
or with a link if you prefer:
<%= link_to(image_tag(client.logo.url(:grayscale), class: 'thumbnail', alt: client.name, title: client.name), client.url ) %>

How to pass additional convert options to paperclip on Heroku?

class User < ActiveRecord::Base
has_attached_file :photo, :styles => { :square => "100%", :large => "100%" },
:convert_options => {
:square => "-auto-orient -geometry 70X70#",
:large => "-auto-orient -geometry X300" },
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":attachment/:id/:style.:extension",
:bucket => 'mybucket'
validates_attachment_size :photo,
:less_than => 5.megabyte
end
Works great on local machine, but gives me an error on Heroku: There was an error processing the thumbnail for stream.20143
The thing is I want to auto-orient photos before resizing, so they resized properly.
The only working variant now(thanks to jonnii) is resizing without auto-orient:
...
as_attached_file :photo, :styles => { :square => "70X70#", :large => "X300" },
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":attachment/:id/:style.:extension",
:bucket => 'mybucket'
...
How to pass additional convert options to paperclip on Heroku?
UPD
I discover, the trouble in "-auto-orient" option. It seems like this option is broken in version of ImageMagick used by Heroku. I created custom paperclip image processor inherited from paperclip's standard thumbnail:
module Paperclip
class Ao < Thumbnail
def transformation_command
super + " -auto-orient"
end
end
end
It works perfect on local machine, but fails on Heroku.
These are the sizes I use. They all work fine on heroku:
SIZES = {
:original => "640x480>",
:thumb => "150x150#",
:mini => "60x60#",
:micro => "30x30#"
}
Make sure your gem version of paperclip is the same as heroku's. You can specify the specific gem version in your .gems file and in your environment.rb to make sure they line up.
I'm not sure exactly why your convert_options are causing problems, but if I remember correctly paperclip uses ImageScience directly and your chosen options might be incompatible with the read only heroku file system.
If this is critical and you need an answer right now I'd raise a support ticket on heroku. If you get a response make sure you post it back here!

Resources