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?
Related
I'm using FastImage on Ruby to resize some images :
https://github.com/sdsykes/fastimage_resize/blob/master/test/test.rb
And this is my code, so I had this error since yesterday :
class IconExport
def initialize(img_url,target_directory,tab)
#img_url=img_url
#target = target_directory
#tab = tab
end
def export
#tab.each do |fn, info|
puts"#{fn} ,#{info}"
outfile = File.join(#target, "fixtures", "resized_" + fn)
puts "#{outfile}"
puts "#{info[1][0] / 3}"
FastImage.resize(#img_url + fn, info[1][0] / 3, info[1][1] / 2, :outfile=>outfile)
assert_equal [info[1][0] / 3, info[1][1] / 2], FastImage.size(outfile)
File.unlink outfile
end
end
end
Error :
icon2.rb:59:in `block in export': uninitialized constant IconExport::FastImage (NameError)
from icon2.rb:54:in `each'
from icon2.rb:54:in `export'
from icon2.rb:82:in `<main>'
Help me please !
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
I want to create new method Integer#to_bin that convert decimal to a binary string. The argument of #to_bin is the number of digits. The result should be padded with leading zeros to make it have that many digits.
Example:
1.to_bin(4)
#=> "0001"
1.to_bin(3)
#=> "001"
1.to_bin(2)
#=> "01"
7.to_bin(1)
#=> nil
7.to_bin
#=> "111"
etс.
What I've tried:
class Integer
def to_bin(number=nil)
if number == nil
return self.to_s(2)
else
s = self.to_s(2).size
e = number-s
one = '0'
two = '00'
three = '000'
if e==one.size
one+self.to_s(2)
elsif e==two.size
two+self.to_s(2)
elsif e==three.size
three+self.to_s(2)
end
end
end
end
How do I convert an integer to a binary string padded with leading zeros?
The appropriate way to do this is to use Kernel's sprintf formatting:
'%03b' % 1 # => "001"
'%03b' % 2 # => "010"
'%03b' % 7 # => "111"
'%08b' % 1 # => "00000001"
'%08b' % 2 # => "00000010"
'%08b' % 7 # => "00000111"
But wait, there's more!:
'%0*b' % [3, 1] # => "001"
'%0*b' % [3, 2] # => "010"
'%0*b' % [3, 7] # => "111"
'%0*b' % [8, 1] # => "00000001"
'%0*b' % [8, 2] # => "00000010"
'%0*b' % [8, 7] # => "00000111"
So defining a method to extend Fixnum or Integer is easy and cleanly done:
class Integer
def to_bin(width)
'%0*b' % [width, self]
end
end
1.to_bin(8) # => "00000001"
0x55.to_bin(8) # => "01010101"
0xaaa.to_bin(16) # => "0000101010101010"
Ruby already has a built-in mechanism to convert a number to binary: #to_s accepts a base to convert to.
30.to_s(2) # => "11110"
If you want to left-pad it with zeroes:
30.to_s(2).rjust(10, "0") => "0000011110"
You could extend this into a little method that combines the two:
class Fixnum
def to_bin(width = 1)
to_s(2).rjust(width, "0")
end
end
> 1234.to_bin
=> "10011010010"
> 1234.to_bin(20)
=> "00000000010011010010"
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
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.