Insert subimage into another image with MiniMagick - ruby-on-rails

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"

Related

How do I preserve the transparent background when converting an SVG file to PNG with MiniMagick in a Ruby on Rails application?

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`

Rails Api Save MiniMagick Image to Active Storage

I'm using MiniMagick to resize my image. My method looks something like that:
def resize
mini_img = MiniMagick::Image.new(img.tempfile.path)
mini_img.combine_options do |c|
c.resize '50x50^'
c.gravity 'center'
c.extent '50x50'
end
mini_img
end
Resize works, but the problem is when I try save mini_img to Active Storage, because I get error Could not find or build blob: expected attachable, got #<MiniMagick::Image. Can I somehow convert MiniMagick::Image (mini_img) to normal image and save it into Active Storage?
Yes, you can. Currently you are trying to save an instance of MiniMagick::Image to ActiveStorage, and that's why you receive that error. Instead you should attach the :io directly to ActiveStorage.
Using your example, if you wanted to attach mini_img to a hypothetical User, that's how you would do it:
User.first.attach io: StringIO.open(mini_img.to_blob), filename: "filename.extension"
In this example I am calling to_blob on mini_img, which is an instance of MiniMagick::Image, and passing it as argument to StringIO#open. Make sure to include the :filename option when attaching to ActiveStorage this way.
EXTRA
Since you already have the content_type when using MiniMagick you might want to provide it to ActiveStorage directly.
metadata = mini_img.data
User.first.attach io: StringIO.open(mini_img.to_blob), filename: metadata["baseName"], content_type: metadata["mimeType"], identify: false
For someone who will have a similar problem. I just changed method to:
def resize
MiniMagick::Image.new(img.tempfile.path).combine_options do |c|
c.resize '50x50^'
c.gravity 'center'
c.extent '50x50'
end
img
end
In this solution, MiniMagick only resized the photo and did nothing else with it, so I didn't have to convert it again.

Errors using the caption method in MiniMagick gem

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 !

MiniMagick Gem: How do I create a new blank image without a file?

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.

Photo Failed to manipulate with MiniMagick, maybe it is not an image? error

I have the following code, which resizes and image and then adds some hex background. On localhost this works, but on heroku i get the following error
version :big do
process :offer_resize_and_pad
end
def offer_resize_and_pad
img = resize_and_pad(600, nil, model.hex, 'Center')
img
end
"Photo Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: Command (\"mogrify -thumbnail \"600x>\" -background \"#fff\" -gravity \"Center\" -extent \"600x\" /tmp/mini_magick20130217-2-1hts61y.jpg\") failed: {:status_code=>1, :output=>\"mogrify: Empty JPEG image (DNL not supported)/tmp/mini_magick20130217-2-1hts61y.jpg' # jpeg.c/EmitMessage/232.\n\"
I 've used RMagick instead of Mini_magick, with some syntax changes , and it seems to work :) .
include CarrierWave::RMagick
def offer_resize_and_pad
img = resize_and_pad(600, 280, model.hex, ::Magick::CenterGravity)
img
end

Resources