How to make white on transparent image using Carrierwave Image magick - imagemagick

I am using Carrierwave with ImageMagick library and i want to convert a image as white on transparent
My uploader.rb
class IconUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
DIMENSIONS = [48,48]
process :white_transparent
def white_transparent
manipulate! do |img|
img.combine_options do |cmd|
cmd.transparent("#ffffff")
cmd.channel "a"
cmd.separate
cmd.negate
end
img = yield(img) if block_given?
img
end
end
def filename
"notification_icon.png"
end
end
I tried the above and i got a "black on white" image as below
I need to convert the image like this
To the images as mentioned below
I want to use converted image as notification icon in Android.
Kindly help.

Related

Carrierwave with MiniMagick is adding black background color to transparent .png when using remote_url with resize_to_[fit/fill/ect]

Expect the following Uploader, when I upload .png with no background via remote_XXX_url the :thumb version using a resize_to_fit is converted with a black background.
The original file uploaded is as the same as the original with the transparent background.
If I upload the image via a file_input the issue is not occurring.
Therefore I deduce that the issue is only occurring when doing a resize_to_XX transformation on remote_XXX_url file. Do you know what is happening ?
carrierwave (2.2.2) -- mini_magick (4.11.0) - The original image has a transparent background.
Image used : https://whirlpool-cdn.thron.com/delivery/public/thumbnail/whirlpool/pi-81b54ac7-7614-4a32-bdd1-a3f79db530d5/sckne7/std/320x320/859791401010.jpg?fill=zoom&fillcolor=rgba:255,255,255&scalemode=product
Thumb Image resized_to_fit
Image without resizing
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
def store_dir
"#{ENV['AWS_S3_BUCKET_NAME']}/#{model.class.to_s.underscore}/#{model.id}"
end
def extension_allowlist
%w(jpg jpeg gif png svg webp)
end
version :thumb do
process resize_to_fit: [150, 150]
end
def filename
#name ||= "#{mounted_as}_#{timestamp}.#{file.extension}" if original_filename.present?
end
def timestamp
var = :"##{mounted_as}_timestamp"
model.instance_variable_get(var) or model.instance_variable_set(var, Time.now.to_i)
end
end
Your original file appears to have the extension .jpg but actually contains a PNG image.
ImageMagick itself is smart enough to spot that and it won't cause you any trouble. I don't know or use carrierwave but it appears to be carrying forward the original .jpg extension and forcing ImageMagick to write a JPEG which will make transparent regions black. I think it's this line:
#name ||= "#{mounted_as}_#{timestamp}.#{file.extension}" if original_filename.present?

Preview of PDF while using Minimagick and Carrierwave in Rails

I've been trying to develop a site that allows for the uploading of various types of documents including pdfs. Below is my uploader:
class PictureUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :jpg do
process :convert_to_images
process :set_content_type_jpg
def convert_to_images(*args)
image = MiniMagick::Image.open(current_path)
image.pages.each_with_index do |page, index|
MiniMagick::Tool::Convert.new do |convert|
convert.background 'white'
convert.flatten
convert.density 300
convert.quality 95
convert << page.path
convert << "#{CarrierWave.root}/#{store_dir}/image-#{index}.jpg"
end
end
end
end
def set_content_type_jpg(*args)
self.file.instance_variable_set(:#content_type, "image/jpg")
end
def extension_whitelist
%w(jpg jpeg gif png pdf)
end
end
So far the site will allow uploads to the server of all of the whitelisted file types, and everything but pdfs will actually display. Pdfs, however, will only show a broken image rather than an image of that pdf. What can I do to fix this?
You should first convert the pdf into a jpg or other image as described here Then try to run the converted file through your above code

How to use carrierwave/minimagick composite to put my logo on the southeast corner of every image uploaded?

I have a model that allows users to upload pictures using carrierwave. I want to put my logo in the southeast corner of each image and then I want the image to save just as it would normally, (example.com/images/1). I know that I have to use composite but despite several hours of googling I am nowhere closer. This was my best guess.
class PictureUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
process resize_to_limit: [400, 400]
process :logo
def logo
manipulate! do |img|
logo = ::MiniMagick::Image.open("#{Rails Name}/app/assets/images/logo.png")
img = img.composite(logo, Magick::SouthEastGravity, 15, 0, Magick::OverCompositeOp)
end
end
I believe you can just change this line
process resize_to_limit: [400, 400]
to this
process resize_to_limit: [400, 400, 'SouthEast']
And then you may or may not need some of that extra minimagick code you were adding about gravity.
process :watermark
def watermark
second_image = MiniMagick::Image.open("https://s3.amazonaws.com/....logo.png")
manipulate! do |img|
img.composite(second_image) do |c|
c.compose "Over" # OverCompositeOp
c.gravity "Southeast" # copy second_image onto first_image from (20, 20)
end
end
end
Got this to work.

In carrierwave, strip image but keep color profile OR convert color profile to sRGB

I'm having basically the same problem here:
How to remove exif from a JPG without losing image quality?
But I'm using Rails and Carrierwave. I'm not sure how Robbert's solution converts to Ruby.
Any help would greatly be appreciated! Thanks!
From the carrierwave docs, you can add something like the following mogrify function to your uploader:
class PhotoUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
process :mogrify
# ...
def mogrify
manipulate! do |img|
img.format('jpg') do |c|
# other options you may want, eg:
# c.auto_orient
convert.profile.+('!icc,!xmp,*')
end
img
end
end
end
which will strip the EXIF data but preserve the ICC and XMP profiles in the JPG.

Carrierwave - Dynamic height/width and cropping

So I got my Carrierwave Uploader which is pretty normal:
class ThumbFileUploader < CarrierWave::Uploader::Base
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
process :resize_to_limit => [2000, 480]
end
In my model I got:
article.remote_thumbnail_url = article.picture_url
What I want to do is
Tell carrierwave the dimensions to use for scaling from within my model
Crop the image if it doesn't fit the exact dimensions after scaling
What's the best practice to accomplish that?
I have had exactly the same problem.
You basically need to have your model store the original image dimensions when the file is first uploaded. You can then use these with jCrop to control the cropping process.
My carrier wave uploaded as this function
def get_geometry
if (#file)
img = ::Magick::Image::read(#file.file).first
#geometry = [ img.columns, img.rows ]
end
end
You have to do rather a lot in the Model, the uploader and in your views.
A full write up is on my web site at the link below.
http://mark.stratmann.me/content_items/image-cropping-with-rails-3-2-carrierwave-bootstrap-modals-jcrop

Resources