Is there an easy way to automatic vertical/horizontal align images with paperclip?
-
22-10-2019 - |
Question
I always want square images of 100x100 but i dont want to scale.
If the it is an image of 100X80 i want it vertical aligned with 10 white pixels on top and 10 white pixels on bottm.
Is there an easy way to handle this?
Using Rails 2.1 with paperclip 2.3.0
Solution 2
Ok i finally managed it.
i used this script to crop the image the way i want.
http://www.fmwconcepts.com/imagemagick/squareup/index.php
I made a new Paperclip processor and named CropFile. I copy pasted the Thumbnail processor from paper clip and added some lines to run the squareup script.
in my model:
has_attached_file :widget_image, :styles => { :square_60 => ["60x60", :png], :square_100 => ["100x100", :png] }, :processors => [:crop_file]
I added paperclip_postprocess.rb in initializers
#paperclip_postprocess.rb
module Paperclip
# Handles thumbnailing images that are uploaded.
class CropFile < Processor
attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options, :source_file_options
# Creates a Thumbnail object set to work on the +file+ given. It
# will attempt to transform the image into one defined by +target_geometry+
# which is a "WxH"-style string. +format+ will be inferred from the +file+
# unless specified. Thumbnail creation will raise no errors unless
# +whiny+ is true (which it is, by default. If +convert_options+ is
# set, the options will be appended to the convert command upon image conversion
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
@source_file_options = options[:source_file_options]
@convert_options = options[:convert_options]
@whiny = options[:whiny].nil? ? true : options[:whiny]
@format = options[:format]
@path = options[:path]
@source_file_options = @source_file_options.split(/\s+/) if @source_file_options.respond_to?(:split)
@convert_options = @convert_options.split(/\s+/) if @convert_options.respond_to?(:split)
@current_format = File.extname(@file.path)
@basename = File.basename(@file.path, @current_format)
# reg exp to get the with and the height
geometry.match(/(\d+)(#|>|<)?x/)
@width = $1
@height = $3
end
# Returns true if the +target_geometry+ is meant to crop.
def crop?
@crop
end
# Returns true if the image is meant to make use of additional convert options.
def convert_options?
!@convert_options.nil? && !@convert_options.empty?
end
# Performs the conversion of the +file+ into a thumbnail. Returns the Tempfile
# that contains the new image.
def make
src = @file
dst = Tempfile.new(['bla', ".png"])
dst.binmode
begin
parameters = []
parameters << source_file_options
parameters << ":source"
parameters << transformation_command
parameters << convert_options
parameters << ":dest"
parameters = parameters.flatten.compact.join(" ").strip.squeeze(" ")
Paperclip.run("convert", parameters, :source => "#{File.expand_path(src.path)}[0]", :dest => File.expand_path(dst.path))
# Cropping it with vertical and horizontal aligning
`#{Rails.root}/public/scripts/squareup.sh -c trans -s #{@width} #{File.expand_path(src.path)} #{File.expand_path(dst.path)}`
rescue PaperclipCommandLineError => e
raise PaperclipError, "There was an error processing the thumbnail for #{@basename}" if @whiny
end
dst
end
# Returns the command ImageMagick's +convert+ needs to transform the image
# into the thumbnail.
def transformation_command
scale, crop = @current_geometry.transformation_to(@target_geometry, crop?)
trans = []
trans << "-resize" << %["#{scale}"] unless scale.nil? || scale.empty?
trans << "-crop" << %["#{crop}"] << "+repage" if crop
trans
end
end
end
I added the following line to crop the images after paperclip has converted them
# Cropping it with vertical and horizontal aligning
`#{Rails.root}/public/scripts/squareup.sh -c trans -s #{@width} #{File.expand_path(src.path)} #{File.expand_path(dst.path)}`
If somebody gets a better idea, please give it to me :)
Thanks
OTHER TIPS
Might not be appropriate, however you can use CSS to easily acchieve this:
html:
<div class="paperclip-holder">
<%= your_paperclip_image_tag %>
</div>
css:
.paperclip-holder{
width: 100px;
height: 100px;
background: #ffffff;
vertical-align: center;
text-align: center;
}