How would I write a Paperclip style to keep the width of the uploaded image at 100% but crop only the height to 60% of the width?
Something like this:
has_attached_file :image, :styles => { :cropped => "100%x[60% of height]" }
has_attached_file :image, :styles => {
:original => "100x60>",
:thumb => Proc.new { |instance| instance.resize }
}
#### End Paperclip ####
def resize
geo = Paperclip::Geometry.from_file(image.to_file(:original))
height = (geo.width.to_i * 60)/100
width = geo.width
"#{width.round}x#{height.round}!"
end
Hope this could help you
has_attached_file :image, :styles => after_save :save_image_dimensions
def save_image_dimensions
geo = Paperclip::Geometry.from_file(image.path)
self.image_height = (geo.height.to_i * 60)/100
end
If you have problem on extract dimension From below you can get a good help
https://github.com/thoughtbot/paperclip/wiki/Extracting-image-dimensions
Please look into this link for cropping images using paperclip
http://viget.com/extend/manual-cropping-with-paperclip
Thanks
Related
I have a two columns on my attachment model on which the user sets the dimension to which they want to resize the image.
However, the variables when the resize happens are nil, but set to actual values after the resize happens.
below is the code
has_attached_file :file, :styles => lambda { |a|
{ :logo => ["200x50>",:png],
:user_defined => ["#{a.instance.custom_width}x#{a.instance.custom_height}>",:png] }
}
the custom_width & custom_height are nil when conversion happens however the logo conversion works as expected.
I am using ruby 2.2.4p230 & Rails 4.2.4
below is the full mode code
class Attachment < ActiveRecord::Base
belongs_to :model_one
belongs_to :attachable, polymorphic: true
#has_attached_file :file, styles: { logo: ['200x50>',:png] }
has_attached_file :file, styles: lambda { |attachment| attachment.instance.styles }
def styles
Rails.logger.info self.inspect
Rails.logger.info self.attachable
styles = {}
m = "200x50>"
l = "#{self.custom_width}x#{self.custom_height}>"
styles[:logo] = [m, :png]
styles[:user_defined] = [l, :png]
styles
end
end
Can anyone please help and let me know if i am doing something wrong?
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
I want Paperclip to crop, and not scale (see :full1 in this excerpt)
class Graphic < ActiveRecord::Base
has_attached_file :image, :styles => { :full0 => "940x1000#" #want it to scale, and crop if neccessary
:full1 => "940#", #want it to crop width, not scale
}
I want :full1 to work, but it doesn't. By "work" I mean it should crop the image's width, but do nothing to it's height. The reason is I'm uploading web screenshots, and I want them to be trimmed to 940px wide (from the center), but their height should remain intact. As far as what I research on paperclip I'm not finding how to do this.
Apparently it's quite supported by ImageMagick: http://www.imagemagick.org/Usage/crop/#crop_strip But I don't know how to jam this into paperclip on rails.
Many thanks!
Could you just set the height to something absurdly large so that it will be a non-issue?
class Graphic < ActiveRecord::Base
has_attached_file :image, :styles => { :full0 => "940x1000#" #want it to scale, and crop if neccessary
:full1 => "940x9999999#", #want it to crop width, not scale
}
I think that will crop anything wider than 940px.
You can user convert options for image process, Following will crop the image centrally.
has_attached_file :profile_picture, :storage => :s3,
:styles => { :medium => "", :thumb => ""},
:convert_options => {
:thumb => Proc.new { |instance| instance.thumnail_dimension },
:medium => Proc.new { |instance| instance.thumnail_dimension(300) }
}
def thumnail_dimension(size=100)
dimensions = Paperclip::Geometry.from_file(profile_picture.queued_for_write[:original].path)
min = dimensions.width > dimensions.height ? dimensions.height : dimensions.width
"-gravity Center -crop #{min}x#{min}+0+0 +repage -resize #{size}x#{size}^"
end
My problem is the next:
I am trying resize a image size depending a proportial size. Example If i have a image whose size is 1440*1000 its new size will be 648*440 (I use a proportion depending a max_size)
NOTE: Then i post my code so you will understand the size relations.
Ok. so I am reading this stackoverflow post:
Getting width and height of image in model in the Ruby Paperclip GEM
Now i post my code and then i will describe my problem.
class ProductImage < ActiveRecord::Base
belongs_to :product, :dependent => :destroy
MAXIMUM_SIZE = 650
has_attached_file :photo, :url => "/:attachment/:class/:id/:style_:basename.:extension", :styles => {:real_size => Proc.new { |instance| instance.real_size }, :original => "400x400>", :medium => "300x300>", :principal => "240x240>", :thumb => "100x100>", :small => "80x50>"}
def real_size
#image = Paperclip::Geometry.from_file(photo.to_file(:maximum_size))
#OBTAIN REAL IMAGE SIZE, NOT ATTACHMENT SIZES
if image_less_than_maximum_size?
return "#{image.width}x#{image.height}"
else
return adjust_image_size(self.width, self.height)
end
end
def adjust_image_size(image_width, image_height)
ratio = (image_width/image_height).to_f
difference_between_size = (image_width - image_height).abs
percentage_difference = ratio > 1 ? difference_between_size * 100.0 / image_width : difference_between_size * 100.0 / image_height
difference_respect_maximum_size = ratio > 1 ? MAXIMUM_SIZE * 100.0 / image_width : MAXIMUM_SIZE * 100.0 / image_height
width = height = 0.0
if ratio > 1
#USE 101.0 FOR INCREMENT OR DECREMENT THE VALUE A LITTLE BIT
width = image_width * difference_respect_maximum_size / 101.0
height = width - (percentage_difference * width / 101.0)
else
heigth = image_height * difference_respect_maximum_size / 101.0
width = height - (percentage_difference * height / 101.0)
end
return "#{width}x#{height}"
end
def image_less_than_maximum_size?
if self.width > self.height
return self.width < MAXIMUM_SIZE
else
return self.height < MAXIMUM_SIZE
end
end
end
My problem is how could i obtain the "real_size"?.
i.e, if image size is "1440*1000" to obtain this size (no attachment size)
UPDATE:
I am thinking a solution. So i think in declare two temp variable to ProductImage model and during initialize method use a before_post_process paperclip callback.
class ProductImage < ActiveRecord::Base
belongs_to :product, :dependent => :destroy
attr_accessor :height, :width
MAXIMUM_SIZE = 650
has_attached_file :photo, :url => "/:attachment/:class/:id/:style_:basename.:extension", :styles => {:real_size => Proc.new { |instance| instance.real_size }, :original => "400x400>", :medium => "300x300>", :principal => "240x240>", :thumb => "100x100>", :small => "80x50>"}
before_post_process :image?
before_post_process :assign_size
...
def assign_size
#width = Paperclip::Geometry.from_file(remote_original_photo_path).width
#height = Paperclip::Geometry.from_file(remote_original_photo_path).height
end
end
Then i could use this size in the other method.
My new problem is how could I determine the remote_original_photo_path in model?
in controller i use the params[:product][:product_images_attributes][index][:photo].
I could save the temp path in model. However because my real_size method during initilize i donĀ“t know how to pass the params info.
Thanks in advance again
With using a gem like image_size ?
[EDIT]
To determine the original upload path may be you can use :
remote_original_photo_path = File.basename(upload['datafile'].original_path)
Trying to get the width and height of the uploaded image while still in the model on the initial save.
Any way to do this?
Here's the snippet of code I've been testing with from my model. Of course it fails on "instance.photo_width".
has_attached_file :photo,
:styles => {
:original => "634x471>",
:thumb => Proc.new { |instance|
ratio = instance.photo_width/instance.photo_height
min_width = 142
min_height = 119
if ratio > 1
final_height = min_height
final_width = final_height * ratio
else
final_width = min_width
final_height = final_width * ratio
end
"#{final_width}x#{final_height}"
}
},
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":attachment/:id/:style.:extension",
:bucket => 'foo_bucket'
So I'm basically trying to do this to get a custom thumbnail width and height based on the initial image dimensions.
Any ideas?
Ahh, figured it out. I just needed to make a proc.
Here's the code from my model:
class Submission < ActiveRecord::Base
#### Start Paperclip ####
has_attached_file :photo,
:styles => {
:original => "634x471>",
:thumb => Proc.new { |instance| instance.resize }
},
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":attachment/:id/:style.:extension",
:bucket => 'foo_bucket'
#### End Paperclip ####
def resize
geo = Paperclip::Geometry.from_file(photo.to_file(:original))
ratio = geo.width/geo.height
min_width = 142
min_height = 119
if ratio > 1
# Horizontal Image
final_height = min_height
final_width = final_height * ratio
"#{final_width.round}x#{final_height.round}!"
else
# Vertical Image
final_width = min_width
final_height = final_width * ratio
"#{final_height.round}x#{final_width.round}!"
end
end
end
class Asset
include Mongoid::Paperclip
before_save :extract_dimensions
field :width, type: Integer
field :height, type: Integer
has_mongoid_attached_file :data
def extract_dimensions
return unless is_image?
tempfile = data.queued_for_write[:original]
unless tempfile.nil?
geometry = Paperclip::Geometry.from_file(tempfile)
self.width = geometry.width.to_i
self.height = geometry.height.to_i
end
true # wont save if false
end
def is_image?
data_content_type =~ %r{^(image|(x-)?application)/(bmp|gif|jpeg|jpg|pjpeg|png|x-png)$}
end
end