How to crop image on upload with Rails, Carrierwave and Minimagick? - ruby-on-rails

I have read:
Undefined Method crop! Using Carrierwave with MiniMagick on rails 3.1.3
Carrierwave Cropping
http://pastebin.com/ue4mVbC8
And so I tried:
# encoding: utf-8
class ProjectPictureUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :thumb do
process :cropper
# process :crop
process resize_to_fit: [200, 200]
end
def cropper
manipulate! do |img|
# if model.crop_x.present?
image = MiniMagick::Image.open(current_path)
crop_w = (image[:width] * 0.8).to_i
crop_y = (image[:height] * 0.8).to_i
crop_x = (image[:width] * 0.1).to_i
crop_y = (image[:height] * 0.1).to_i
# end
img = img.crop "#{crop_x}x#{crop_y}+#{crop_w}+#{crop_h}"
img
end
end
def crop
if model.crop_x.present?
resize_to_limit(700, 700)
manipulate! do |img|
x = model.crop_x
y = model.crop_y
w = model.crop_w
h = model.crop_h
w << 'x' << h << '+' << x << '+' << y
img.crop(w)
img
end
end
end
end
Then I used cropper: undefined local variable or method `crop_h' for /uploads/tmp/20121006-2227-4220-9621/thumb_Koala.jpg:#
Then crop: undefined method `crop_x' for #
Model:
class Project < ActiveRecord::Base
...
mount_uploader :picture, ProjectPictureUploader
end
Rails 3.2, Win7,
convert -version
Version: ImageMagick 6.7.9-4 2012-09-08 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
Features: OpenMP

I have understood.
version :thumb do
process resize_to_fit: [300, nil]
process crop: '300x150+0+0'
#process resize_and_crop: 200
end
private
# Simplest way
def crop(geometry)
manipulate! do |img|
img.crop(geometry)
img
end
end
# Resize and crop square from Center
def resize_and_crop(size)
manipulate! do |image|
if image[:width] < image[:height]
remove = ((image[:height] - image[:width])/2).round
image.shave("0x#{remove}")
elsif image[:width] > image[:height]
remove = ((image[:width] - image[:height])/2).round
image.shave("#{remove}x0")
end
image.resize("#{size}x#{size}")
image
end
end
resize_and_crop from here:
http://blog.aclarke.eu/crop-and-resize-an-image-using-minimagick/

In #cropper your crop_h is not initialized(you double initialize crop_y instead).
In #crop error is exactly what error message said - you don't have defined crop_x for Project class.

Related

Paperclip watermark processor

I'm having issues to execute command in my processor. The same command works in console. Basically, I need to use two commands in one - convert and composite with tile so that watermark is repeated all over the image.
The command I ran in console is this:
run_string = "convert utah.jpg -resize 1200x1200 miff:- | composite -tile Watermark-Photo.png - utah2.jpg"=> "convert utah.jpg -resize 1200x1200 miff:- | composite -tile Watermark-Photo.png - utah2.jpg"
Paperclip.run run_string
And the result was perfect. However, when I put it into my processor:
module Paperclip
class Watermark < Processor
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]
#watermark_offset = options[:watermark_offset]
#overlay = options[:overlay].nil? ? true : false
#current_format = File.extname(#file.path)
#basename = File.basename(#file.path, #current_format)
Rails.logger.info "watermark initialized"
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?
not #convert_options.blank?
end
# Performs the conversion of the +file+ into a watermark. Returns the Tempfile
# that contains the new image.
def make
Rails.logger.info "watermark make method"
src = #file
dst = Tempfile.new([#basename].compact.join("."))
dst.binmode
if #watermark_path.present?
# params = ["convert"]
# params += %W[#{fromfile}]
# params += transformation_command
# params += %W[| composite -tile #{#watermark_path} -]
# params << "#{tofile(dst)}"
run_string = "convert '#{fromfile}' #{transformation_command.join(' ')} | composite -tile '#{#watermark_path}' - '#{tofile(dst)}'"
else
# params = ["convert"]
# params += ["'#{fromfile}'"]
# params += transformation_command
# params << "'#{tofile(dst)}'"
run_string = "convert '#{fromfile}' #{transformation_command.join(' ')} '#{tofile(dst)}'"
end
Rails.logger.info 'params:' + run_string
begin
# Paperclip.run(params.join(' '))
Paperclip.run(run_string)
rescue ArgumentError, Cocaine::CommandLineError
raise Paperclip::Error.new("There was an error processing the watermark for #{#basename}") if #whiny
end
dst
end
def transformation_command
scale, crop = #current_geometry.transformation_to(#target_geometry, crop?)
trans = %W[-resize #{scale}]
trans += %W[-crop #{crop} +repage] if crop
trans += %W[miff:- ]
trans << #convert_options if #convert_options.present?
trans
end
def fromfile
File.expand_path(#file.path)
end
def tofile(destination)
File.expand_path(destination.path)
end
end
end
I can see from log that it executes the command:
Command :: convert '/tmp/7179f28e8260099624b8c2e7e8fe8fb420170902-1-1ud7pah.jpg' -resize 600x600> miff:- | composite -tile '/storycraftstock/app/assets/images/Watermark-Photo.png' - '/tmp/7179f28e8260099624b8c2e7e8fe8fb420170902-1-1ud7pah20170902-1-1kbmamu'
Gives this unspecific error:
exception while processing Spree::Image ID 11:
There was an error processing the watermark for 32a2a05e7393f7ddc78f0134bcf32e4a20170902-1-19oyq1j
As you can see I've commented a lot of things in the code just to make it run, but still no luck. Any ideal what am I doing wrong?

Change order of Paperclip image processors

I am using Paperclip to create a thumbnail and apply a watermark to an uploaded image. The problem is that the thumbnail is created from a watermarked image instead of the original.
How can I make a thumbnail from the original file?
Model
has_attached_file :image,processors:[:thumbnail, :watermark], styles:{thumb:"240x240#", original: {watermark_path: "#Rails.root}/public/images/watermark.png"}}
Watermark Processor
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
if geometry.present?
#crop = geometry[-1, 1] == '#'
end
#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
# 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?
not #convert_options.blank?
end
# Performs the conversion of the +file+ into a watermark. Returns the Tempfile
# that contains the new image.
def make
return #file unless watermark_path
dst = Tempfile.new([#basename, #format].compact.join("."))
dst.binmode
command = "convert"
params = [fromfile]
params += transformation_command
params << tofile(dst)
begin
success = Paperclip.run(command, params.flatten.compact.collect { |e| "'#{e}'" }.join(" "))
rescue Paperclip::Errors::CommandNotFoundError
raise Paperclip::Errors::CommandNotFoundError, "There was an error resizing and cropping #{#basename}" if #whiny
end
if watermark_path
command = "composite"
params = %W[-gravity #{#position} #{watermark_path} #{tofile(dst)}]
params << tofile(dst)
begin
success = Paperclip.run(command, params.flatten.compact.collect { |e| "'#{e}'" }.join(" "))
rescue Paperclip::Errors::CommandNotFoundError
raise Paperclip::Errors::CommandNotFoundError, "There was an error processing the watermark for #{#basename}" if #whiny
end
end
dst
end
def fromfile
File.expand_path(#file.path)
end
def tofile(destination)
File.expand_path(destination.path)
end
def transformation_command
if #target_geometry.present?
scale, crop = #current_geometry.transformation_to(#target_geometry, crop?)
trans = %W[-resize #{scale}]
trans += %W[-crop #{crop} +repage] if crop
trans << convert_options if convert_options?
trans
else
scale, crop = #current_geometry.transformation_to(#current_geometry, crop?)
trans = %W[-resize #{scale}]
trans += %W[-crop #{crop} +repage] if crop
trans << convert_options if convert_options?
trans
end
end
end
end

Reading uploaded image: undefined method `file' for nil:NilClass

I receive the following error when I try to get image during thumbnail creation:
undefined method `file' for nil:NilClass
My code:
version :thumb do
img = ::Magick::Image::read(#file.file).first
w = img.columns
h = img.rows
if w < h
process :resize_to_limit => [30, 50]
else
process :resize_to_limit => [50, 30]
end
end
Any ideas what is this not working?

Clean Image Attachment for OCR in Ruby-On-Rails

How can I use a script such as Textcleaner within a Ruby-On-Rails application? Currently I'm using a custom paperclip processor where I use parameters similar to the script. Here is the has_attached_file line in my ActiveRecord:
has_attached_file :file, :style=> { :processors => [:text_cleaner] } }
Here is the Paperclip Processor:
module Paperclip
# Handles grayscale conversion of images that are uploaded.
class TextCleaner< 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 << "-auto-orient"
parameters << "-colorspace Gray"
#parameters << "-sharpen 0x1"
#parameters << "-type grayscale"
#parameters << "-contrast-stretch 0"
#parameters << "-clone 0"
#parameters << "-deskew 40%"
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
Using paperclip I was able to add a Text Cleaner processor. I added it as a style in model via:
has_attached_file :file, :styles => { :clean => { :processors => [:text_cleaner] } }
And in /lib/paperclip_processors/text_cleaner.rb I have:
module Paperclip
# Handles grayscale conversion of images that are uploaded.
class TextCleaner < 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 = '-respect-parenthesis \( :source -colorspace gray -type grayscale -contrast-stretch 0 \) \( -clone 0 -colorspace gray -negate -lat 15x15+5% -contrast-stretch 0 \) -compose copy_opacity -composite -fill "white" -opaque none +matte -deskew 40% -auto-orient -sharpen 0x1 :dest'
success = Paperclip.run('convert', parameters, :source => File.expand_path(#file.path), :dest => File.expand_path(dst.path))
rescue PaperclipCommandLineError => e
raise PaperclipError, "There was an error during the textclean conversion for #{#basename}" if #whiny
end
dst
end
end
end

Rails + Paperclip + AWS: After watermark is added, new picture is not sent to Amazon s3

I added watermark processor for one size of image. But, all other versions of picture are uploaded to S3, except this one. I believe I had to notify AWS that I changed this size but I do not know how or where to do that...
Here is my code:
lib/paperclip_processors/watermark.rb
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]
#format_output = options[:format_output].nil? ? "jpg" : options[:format_output]
#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
# Performs the conversion of the +file+ into a watermark. Returns the Tempfile
# that contains the new image.
def make
dst = Tempfile.new([#basename, #format].compact.join("."))
dst.binmode
if watermark_path
command = "composite"
params = %W[-gravity #{#position}]
params += %W[-geometry '#{#watermark_offset}'] if #watermark_offset
params += %W["#{watermark_path}" "#{fromfile}"]
params += transformation_command
params << "\"#{tofile(dst)}.#{#format_output}\""
else
command = "convert"
params = [fromfile]
params += transformation_command
params << tofile(dst)
end
puts command
puts "Params: " + params.to_s
begin
success = Paperclip.run(command, params.join(" "))
rescue ArgumentError, Cocaine::CommandLineError
raise Paperclip::Error, "There was an error processing the watermark for #{#basename}" if #whiny
end
dst
end
def fromfile
File.expand_path(#file.path)
end
def tofile(destination)
File.expand_path(destination.path)
end
def transformation_command
scale, crop = #current_geometry.transformation_to(#target_geometry, crop?)
trans = %W[-resize "#{scale}"]
trans += %W[-crop #{crop} +repage] if crop
trans << convert_options if convert_options?
trans
end
end
end
and model:
require 'paperclip_processors/watermark'
class Price < ActiveRecord::Base
has_attached_file :picture,
:processors => [:watermark],
styles: {
thumb: '100x100#',
small: '320x200#',
medium: '640x400#',
large: {
:geometry => "920x575>",
:watermark_path => "#{Rails.root}/public/img/watermark.png"
}
}
end

Resources