I'm creating a collage of thumbnails using Ruby 1.9.3. The thumbnails are being loaded as follows:
image1 = MiniMagick::Image.open("1.jpg")
image2 = MiniMagick::Image.open("2.jpg")
image2.rotate "-45>"
image3 = MiniMagick::Image.open("3.jpg")
image3.rotate "45>"
I've never used ImageMagick or MiniMagick before and I've got the code for compositing images from the minimagick GitHub page.
collage = MiniMagick::Image.create "jpg", false do |c|
c.size "1024x768"
c.canvas "white"
end
collage = collage.composite image1 do |c|
c.gravity "center"
end
collage = collage.composite image2 do |c|
c.gravity "east"
end
collage = collage.composite image3 do |c|
c.gravity "west"
end
collage.write("output.jpg")
The problem is coming up on the Image.create command. When I run the file using
$ ruby prog.rb
I get the following error
/Users/vinayshenoy/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/tempfile.rb:250:in `size': wrong number of arguments (1 for 0) (ArgumentError)
from prog.rb:14:in `block in <main>'
from /Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/mini_magick-3.4/lib/mini_magick.rb:158:in `call'
from /Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/mini_magick-3.4/lib/mini_magick.rb:158:in `create'
from prog.rb:13:in `<main>'
The script file is the same directory as the images. I tested by writing image1, image2 and image3 to separate files and they all work. Please help.
The error message is a bit strange, but according to the documentation at http://www.imagemagick.org/script/command-line-options.php?#composite composite only takes 3 arguments - the two images you want to combine (the image you create in line 1 and the one called image 1), plus a gray scale 'mask' (image2 in this case).
In other words, it seems like you'll have to save after every single one of the three compositions.
Related
I am trying to automatically convert SVG images to PNG with Minimagick. I have a Rails application where I need to automatically convert uploaded SVG files. The app runs on Heroku. These SVGs typically have a transparent background.
This is the code I am using:
class MyUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
version :email do
process :convert_to_png
def full_filename (for_file = model.logo.file)
"#{model.friendly_id}-#{model.id}-logo-email.png"
end
end
def convert_to_png
manipulate! do |img|
img = img.format 'png'
img = img.density 300
img = img.resize '800x400'
img = img.background 'none'
end
end
end
This creates a png image with width 800. However the property background 'none' is not applied. The original image has a transparent background, and the resulting converted image has a white background instead.
I have seen that Minimagick calls the mogrify command of Imagemagick, and I have found the command I have to call to create the image I need, but I have trouble converting it into a function for the uploader. Using the same parameters in the same sequence for the uploader doesn't work because it throws an error if the line img = img.format 'png' isn't called first.
mogrify -density 300 -background none -resize 400x200 -format png myfile.svg
Note: I don't use this library so all of this is gleaned from the docs and the source code. If these don't work for you I will remove the post it was just too long for a comment
Here are few suggestions:
Maybe try combine_options instead? "MiniMagick::Image#combine_options takes multiple options and from them builds one single command." which is more in line with your desired CLI call
def convert_to_png
manipulate! do |img|
img.combine_options do |i|
i.density 300
i.background 'none'
i.resize '800x400'
i.format 'png'
end
end
end
Another option is to touch the Metal and generate that exact command.
MiniMagick::Tool::Mogrify.new do |mogrify|
mogrify << "input.svg"
mogrify.density(300)
mogrify.background('none')
mogrify.resize('800x400')
mogrify.format('png')
mogrify << "output.png"
end
#=> `mogrify input.svg -density 300 -background none -resize 800x400 -format png output.png`
I'm trying to build a rails app that generates an image by overlaying a text over a default image.
I'm almost there - by using carrierwave + mini magick i have this method working :
def generate_image
message = self.description.upcase
image = MiniMagick::Image.open('public/base.jpg')
image.combine_options do |c|
c.size '400x500'
c.gravity 'NorthWest'
c.fill 'black'
c.strokewidth '2'
c.pointsize '48'
c.interline_spacing '-9'
c.font "#{Rails.root}/public/black.ttf"
c.draw "text 40,40 '#{message}'"
c.antialias
end
self.image = image
end
the problem is that i want my text to fit the size i've specified - but I had no luck !
reading the Image Magick documentation I know that I should use the "capition" method instead of draw - but when I do so it throws out an orrible error :) :
failed with error: mogrify: no encode delegate for this image format `CAPTION' #
error/constitute.c/WriteImage/1167.
any clues ?
thanks !
Versions:
Ruby 2.2.3
Rails 4.2.4
mini_magick: 4.2.10
Carrierwave 0.10.0
Description
I am trying to create a watermarker for a small gallery using CarrierWave as uploader.
I want the watermark to be sized compared to the current image. Therefore I am trying to use a .svg-file with different opacities and a transparent background.
I am using a watermarker based on Carrierwave add a watermark to processed images
require 'mini_magick'
class Watermarker
def initialize(original_path, watermark_path)
#original_path = original_path.to_s
#watermark_path = watermark_path.to_s
end
def watermark!(options = {})
options[:gravity] ||= 'SouthEast'
image = MiniMagick::Image.open(#original_path)
watermark = MiniMagick::Image.open(#watermark_path)
result = image.composite(watermark, 'png') do |c|
c.gravity options[:gravity]
end
result.write #original_path
end
end
And calling this as a process from my uploader.
My problems:
I cannot get the watermarker to input the picture with transparent background. I played around with:
https://github.com/minimagick/minimagick#composite
http://www.imagemagick.org/script/composite.php
But no progress.
I cannot adjust the size of the overlay image properly. There is a lot of settings for the geometry command but I'm stuck.
Any ideas and help would be great.
I want to combine two images (one background image, one text image) into one big image.
I believe I have the background image done since it's just based off a file. However, I'm having trouble trying to create an image from scratch. Any tips?
image = MiniMagick::Image.open("public/text_response_bg.png")
image.combine_options do |i|
i.size "1024x512"
end
text = MiniMagick::Image.new #<-- does not work
text.combine_options do |i|
i.size "700x200"
i.gravity 'center'
i.fill 'white'
i.caption 'blahblahblah'
end
result = image.composite(text) do |c|
c.compose "Over"
c.geometry "+20+20"
end
Create an image from scratch with the following Ruby Code:
MiniMagick::Tool::Convert.new do |i|
i.size "700x200"
i.gravity "center"
i.xc "white"
i.caption "blablabla"
i << "test_image.jpg"
end
MiniMagick provide a method MiniMagick::Image.create to create a new image but seems not work with this issues
Use ImageMagick primary command you can create a pure color image like
convert -size 800x600 xc:"#ffffff" write.jpg
So if not mind using system command to create image you can do:
cmd = "convert -size 800x600 xc:'#ffffff' WRITE_IMAGE.jpg"
system(cmd)
UPDATE: I use MiniMagick 3.8.0, and see latest version 4.0.1 has a MiniMagick::Shell class, think it could run that custom ImageMagick command directly.
I'm looking to write the Carrierwave process to add a subimage into another image with MiniMagick, any ideas ?
This doc https://github.com/probablycorey/mini_magick say we can use all the mogrify commandline options of ImageMagick, but don't I need composite to do it ?
Thank you.
I have to open my eyes, this is written in the MiniMagick doc:
image = MiniMagick::Image.open("original.png")
result = image.composite(MiniMagick::Image.open("watermark.png", "jpg")) do |c|
c.gravity "center"
end
result.write "my_output_file.jpg"