Is there any way to set new dimensions to my_image and save it to AWS S3?
I have
my_image = Post.last.photo.image
geometry = Paperclip::Geometry.from_file(my_image.url)
so i want to set new geometry and save it
geometry = 'my params'
my_image.save
Of course i have my
has_attached_file :image, :styles => { :large => "220x" ..other styles}
My main goal set new dimensions during cropping photo with Jcrop
so when i receive new params like my_params=>"crop_x"=>"83", "crop_y"=>"24", "crop_w"=>"76", "crop_h"=>"76" set it as new style inside has_attached_file
You can do that easily,
Declare attribute accessors for the crop dimensions
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
Then you need to override the processor, create cropper.rb in /lib/paperclip_processors and add following code
module Paperclip
class Cropper < Thumbnail
def transformation_command
if crop_command
crop_command + super.join(' ').sub(/ -crop \S+/, '').split(' ') # super returns an array like this: ["-resize", "100x", "-crop", "100x100+0+0", "+repage"]
else
super
end
end
def crop_command
target = #attachment.instance
if target.cropping?
["-crop", "#{target.crop_w}x#{target.crop_h}+#{target.crop_x}+#{target.crop_y}"]
end
end
end
end
Now in the model you can do this
has_attached_file :image, styles: { large: "800X800>" }, default_url: "/images/:style/missing.png", :processors => [:cropper]
after_save :reprocess_image, if: :cropping?
def cropping?
!crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
end
def reprocess_image
image.assign(image)
image.save
end
Hope this helps!
Related
I have a custom processor for my Paperclip styles: cropper.rb. Though it is not called and return NameError (uninitialized constant Paperclip::Cropper) error.
It has been discussed here : Rails3 and Paperclip but a while ago. It was concerning Rails 3 back then.
I am under Rails 5 (update from Rails 4.x)
Profilepic.rb
class Profilepic < ApplicationRecord
belongs_to :professionnels
has_attached_file :image, styles: { big: "1200x1200", medium: "400x400", small: "250x250"}
validates_attachment :image, content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] }, size: {less_than: 10.megabytes}
has_attached_file :finalimage, styles: { medium: "500x500", small: "200x200"}, whiny: false, use_timestamp: false, processors: [:cropper]
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
end
lib/paperclip_processors/cropper.rb
module Paperclip
class CustomCropper < Thumbnail
def initialize(file, options = {}, attachment = nil)
super
if target.crop_w && target.crop_x
#current_geometry.width = target.crop_w
#current_geometry.height = target.crop_h
end
end
def target
#attachment.instance
end
def transformation_command
# call crop processing only if user inputs are there
if target.crop_w && target.crop_x
crop_command = [
"-crop",
"#{target.crop_w}x" \
"#{target.crop_h}+" \
"#{target.crop_x}+" \
"#{target.crop_y}",
"+repage"
]
crop_command + super
else
super
end
end
end
end
OK spent a day to realize the correct lib subfolder is actually paperclip and not paperclip_processors although Paperclip Git does mention both as valid and automatically loaded.
I try apply watermark to my paperclip, it keep show error message and unable update/upload image. It keep show **
uninitialized constant Paperclip::Watermark::PaperclipCommandLineError
**
gem file
gem "paperclip", '4.2' gem 'rails', '4.2.6' gem
'paperclip-compression'
paperclip_processors/watermark.rb
module Paperclip
class Watermark < Thumbnail
def initialize(file, options = {}, attachment = nil)
super
#watermark_path = options[:watermark_path]
#position = options[:position].nil? ? "SouthEast" : options[:position]
end
def make
src = #file
dst = Tempfile.new([#basename].compact.join("."))
dst.binmode
return super unless #watermark_path
params = "-gravity #{#position} #{transformation_command.join(" ")} #{#watermark_path} :source :dest"
begin
success = Paperclip.run("composite", params, :source => "#{File.expand_path(src.path)}[0]", :dest => File.expand_path(dst.path))
rescue PaperclipCommandLineError
raise PaperclipError, "There was an error processing the watermark for #{#basename}" if #whiny
end
dst
end
end
end
lisitng.rb
class Listing < ActiveRecord::Base
require 'paperclip_processors/watermark'
has_attached_file :image,
:processors => [:watermark],
:styles => {
:medium => {
:geometry => "300x300>",
:watermark_path => "#{Rails.root}/public/images/watermark.png"
},
:thumb => "100x100>",
}
I think you're subclassing wrong. Don't subclass Thumbnail, subclass Paperclip::Processor
module Paperclip
class Watermark < Processor
...
https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/processor.rb
I am trying to implement the steps to check and resize images with paperclip based on this blog post: http://www.techdarkside.com/how-to-re-size-images-that-are-too-large-on-the-fly-with-paperclip-and-rails
Here is what I have in place...
class Question < ActiveRecord::Base
# subclasses
class Question::Image < Asset
has_attached_file :attachment,
:url => "/uploads/:class/:attachment/:id_partition/:basename_:style.:extension",
:styles => Proc.new { |attachment| attachment.instance.styles },
:styles => Proc.new { |attachment| attachment.instance.resize }
attr_accessible :attachment
# http://www.ryanalynporter.com/2012/06/07/resizing-thumbnails-on-demand-with-paperclip-and-rails/
def dynamic_style_format_symbol
URI.escape(#dynamic_style_format).to_sym
end
def styles
unless #dynamic_style_format.blank?
{ dynamic_style_format_symbol => #dynamic_style_format }
else
{ :medium => "300x300>", :thumb => "100x100>" }
end
end
def dynamic_attachment_url(format)
#dynamic_style_format = format
attachment.reprocess!(dynamic_style_format_symbol) unless attachment.exists?(dynamic_style_format_symbol)
attachment.url(dynamic_style_format_symbol)
end
def resize
if self.attachment_file_size > 2000000
"300x300>"
else
" "
end
end
end
I'm thinking the issue is with the reuse of the :styles symbol, however I'm not sure how to work both the styles method AND the resize method into a single Proc statement.
Here is what I ended up with thanks to #janfoeh suggestion. I did need to add :originalto the options in style to get this to work. I also bumped the max file size up to 5mb.
class Question < ActiveRecord::Base
# subclasses
class Question::Image < Asset
has_attached_file :attachment,
:url => "/uploads/:class/:attachment/:id_partition/:basename_:style.:extension",
:styles => Proc.new { |attachment| attachment.instance.styles }
attr_accessible :attachment
# http://www.ryanalynporter.com/2012/06/07/resizing-thumbnails-on-demand-with-paperclip-and-rails/
def dynamic_style_format_symbol
URI.escape(#dynamic_style_format).to_sym
end
def styles
unless #dynamic_style_format.blank?
{ dynamic_style_format_symbol => #dynamic_style_format }
else
{ :original => resize, :medium => "300x300>", :thumb => "100x100>" }
end
end
def dynamic_attachment_url(format)
#dynamic_style_format = format
attachment.reprocess!(dynamic_style_format_symbol) unless attachment.exists?(dynamic_style_format_symbol)
attachment.url(dynamic_style_format_symbol)
end
def resize
if self.attachment_file_size > 5000000
"1000x1000>"
else
" "
end
end
end
My rails app uses Paperclip and ImageMagick to process uploaded photos.
I currently have it set up like this
as_attached_file :photo, :styles => { :original => "1500x1500>", :thumb => "400x400>#", :large => "1080x1080>" }, :convert_options => { :thumb => '-quality 60', :large => '-quality 60'}, :default_url => "/missing.png"
If someone uploads an image with dimension 1000x100 (10:1 aspect ratio) for example I would like to limit the aspect ratio (on the :large and :original) so that it will crop the image if the aspect ratio is too extreme.
ie: if ratio is beyond 4:1 or 1:4 then crop
The best way to do this is to implement a custom processor. That way you can implement your logic and decide when to change the image the way you want.
See an example implementation of a custom processor. In my case I needed to apply a watermark on the images.
lib/paperclip_processors/watermark.rb
module Paperclip
class Watermark < Thumbnail
attr_accessor :format, :watermark_path, :watermark_gravity, :watermark_dissolve
def initialize file, options = {}, attachment = nil
super
#file = file
#format = options[:format]
#watermark_path = options[:watermark_path]
#watermark_gravity = options[:watermark_gravity].nil? ? "center" : options[:watermark_gravity]
#watermark_dissolve = options[:watermark_dissolve].nil? ? 40 : options[:watermark_dissolve]
#current_format = File.extname(#file.path)
#basename = File.basename(#file.path, #current_format)
end
def make
return #file unless watermark_path
dst = Tempfile.new([#basename, #format].compact.join("."))
dst.binmode
command = "composite"
params = "-gravity #{#watermark_gravity} -dissolve #{#watermark_dissolve} #{watermark_path} #{fromfile} #{tofile(dst)}"
begin
success = Paperclip.run(command, params)
rescue PaperclipCommandLineError
raise PaperclipError, "There was an error processing the watermark for #{#basename}"
end
dst
end
def fromfile
"\"#{ File.expand_path(#file.path) }[0]\""
end
def tofile(destination)
"\"#{ File.expand_path(destination.path) }[0]\""
end
end
end
models/image.rb
has_attached_file :file,
processors: [:thumbnail, :watermark],
styles: {
layout: "100%",
preview: {geometry: "900x900>", watermark_path: "#{Rails.root}/app/assets/images/watermarks/watermark_200.png"},
thumbnail: "300x300>",
miniature: "150x150>"
},
convert_options: {
layout: "-units PixelsPerInch -density 100",
preview: "-units PixelsPerInch -density 72",
thumbnail: "-units PixelsPerInch -density 72",
miniature: "-units PixelsPerInch -density 72"
}
You can refer to the documentation for custom processors:
https://github.com/thoughtbot/paperclip#custom-attachment-processors
according to this example (http://dimaspriyanto.com/2010/06/08/image-watermarking-with-paperclip/), I try to put a watermark on every picture I upload (for now, I restrain myself to the large one).
And guess what? It doesn't work!
So in my picture model, I have
require 'paperclip_processors/watermark'
has_attached_file :image,
:styles => {:medium => "300x300^", :thumb => "150x105^",
:large => {
:geometry => "460",
:watermark_path => ":rails_root/public/images/watermark.png"
}
},
:url => "/images/:style/:id_:style.:extension",
:path => ":rails_root/public/images/:style/:id_:style.:extension"
and in /lib/paperclip_processors/watermark.rb, I have:
module Paperclip
class Watermark < Processor
attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options, :watermark_path, :overlay, :position
def initialize file, options = {}, attachment = nil
super
geometry = options[:geometry]
#file = file
#crop = geometry[-1,1] == '#'
#target_geometry = Geometry.parse geometry
#current_geometry = Geometry.from_file #file
#convert_options = options[:convert_options]
#whiny = options[:whiny].nil? ? true : options[:whiny]
#format = options[:format]
#watermark_path = options[:watermark_path]
#position = options[:position].nil? ? "SouthEast" : options[:position]
#overlay = options[:overlay].nil? ? true : false
#current_format = File.extname(#file.path)
#basename = File.basename(#file.path, #current_format)
end
def crop?
#crop
end
def convert_options?
not #convert_options.blank?
end
def make
dst = Tempfile.new([#basename, #format].compact.join("."))
dst.binmode
if watermark_path
command = "composite"
params = "-gravity #{#position} #{watermark_path} #{fromfile} #{transformation_command} #{tofile(dst)}"
else
command = "convert"
params = "#{fromfile} #{transformation_command} #{tofile(dst)}"
end
begin
success = Paperclip.run(command, params)
rescue PaperclipCommandLineError
raise PaperclipError, "There was an error processing the watermark for #{#basename}" if #whiny
end
dst
end
def fromfile
"\"#{ File.expand_path(#file.path) }[0]\""
end
def tofile(destination)
"\"#{ File.expand_path(destination.path) }[0]\""
end
def transformation_command
scale, crop = #current_geometry.transformation_to(#target_geometry, crop?)
trans = "-resize \"#{scale}\""
trans << " -crop \"#{crop}\" +repage" if crop
trans << " #{convert_options}" if convert_options?
trans
end
end
end
The watermark is in /public/images/ and it doesn't crash in the process, I mean the pictures are uploaded, in every size but the large one is nude, without the watermark.
Any idea?
Here's the preprocessor that works (I use it)
https://gist.github.com/2499137
Here's sample code for you model:
has_attached_file :data,
:processors => [:watermark],
:url => "/ckeditor_assets/pictures/:id/:style_:basename.:extension",
:path => ":rails_root/public/ckeditor_assets/pictures/:id/:style_:basename.:extension",
:styles => {
:thumb => '118x100#',
:content => {
:geometry => '700>',
:watermark_path => "#{Rails.root}/public/images/watermark.png",
:position => 'SouthWest'
},
}