GraphicsMagick / ImageMagick replace all non-transparent pixels (like Photoshop's Color Overlay) - node.js

I'm trying to replace all non-transparent pixels to a given color using GraphicsMagick for Node.
Using a composite image is not an option, I simply need to change every non-transparent pixel to a given color.
Original image:
Goal:
Transparent pixels should stay transparent. I'm trying to achieve Photoshop's Color Overlay effect:

This is a bit simpler. In ImageMagick do the following:
convert 84xHk.png -fill "#E91FCB" +opaque none result.png

I'm not familiar with Node's GraphicsMagick library, but there are a few methods to achieve this. Here's a few I can think of...
Extract alpha, and replace colors
convert 84xHk.png -alpha extract \
-negate -fill '#E91FCB' -fuzz 50% \
-opaque black output.png
Create solid color image, and copy alpha channel
convert 84xHk.png \
\( +clone -alpha off \
-fill '#E91FCB' \
-draw 'color 0,0 reset' \
\) +swap -compose CopyOpacity -composite output.png
Use FX expressions
convert 84xHk.png -fx 'p.a==1?#E91FCBFF:#E91FCB00' output.png

Related

Can't fit text to image with ImageMagick

I need to fit my text to image. My image have different sizes so i can't set constant pointsize.
My command looks something like this
convert
-fill white
-font Winter Calligraphy
-size `${options.width}x${options.height}`
label: KJHGFD
test.gif
on output you can see cropped part on top of picture.
Output:
I have problem only with this fonts, other fonts works great.
I tried to add white border on top. Unfortunately, this only moved the damaged text to bottom.
I can't change area size.
Text must fill as much space as possible.
I need to use Winter Calligraphy font
Here is a slightly kludgy way of getting the result you want. Here are the steps:
First, use caption: to get ImageMagick to tell you the pointsize it would use to fill your text box and extract that info
Create a canvas twice as wide and twice as tall as the one you really want and draw your text in the middle of that - it is bound to fit!
Now trim away the extraneous background around the text so you have the absolute minimum bounding box to contain the text
Resize the result to your desired size.
#!/bin/bash
# Width, height and text
w=600
h=150
text="KJHGFD"
# Get pointsize ImageMagick thinks is good
pointsize=$(convert -gravity center -background black -fill white -size ${w}x${h} \
-font "Winter Calligraphy.ttf" caption:"$text" -format "%[caption:pointsize]" info:)
echo ImageMagick likes pointsize: $pointsize
# So draw text in that size on larger canvas, trim to bounds of letters and resize to desired size
wb=$((w*2))
hb=$((h*2))
convert -gravity center -fill white -size ${wb}x${hb} xc:black \
-font "Winter Calligraphy.ttf" -pointsize $pointsize -annotate 0 "$text" \
-trim +repage -resize ${w}x${h}\! result.png
This works for me in ImageMagick 6.9.10.97 Q16 Mac OSX. I have added -background white -fill black -gravity center to your command.
convert -background white -fill black -font "/library/fonts/Winter Calligraphy.ttf" -size 569x196 -gravity center label:KJHGFD test.gif

How can I create a new image with support of alpha channel with Graphicsmagick in NodeJS

I want to create a grid image with white lines and alpha channel so I can compose this on another image. How can I apply alpha channel to gridImage instance instead of a solid background and how can I change the color of the drawn lines with drawLine method ?
var gridImage = new gm(imageWidth,imageHeight,"white");
gridImage.channel("Opacity");
gridImage.drawLine(10,0,10,200);
gridImage.strokeWidth(3);
gridImage.borderColor("white");
gridImage.fill("white");
I don't speak node because I am allergic to all those parentheses, and I don't understand exactly what you are trying to achieve, but I can show you something that may help you work out how to do what you want - hopefully.
I am using ImageMagick but the concept is similar. The following command creates a solid magenta square of 100x100. It then creates a smaller, 50x50 pattern in black and white and copies that into the opacity channel so that the smaller 50x50 square gets holes punched in it.
magick -size 100x100 xc:magenta \
\( -size 50x50 pattern:HS_CROSS -negate \) \
-compose copyopacity -composite result.png
Here's another one:
magick -size 100x100 xc:cyan \
\( -size 100x100 xc:white -fill black -draw "circle 50,50 50,60" -alpha off \) \
-compose copyopacity -composite result.png

Adding an overlay to og:image

I need to generate watermarked embed-image for Facebook in NodeJs. I noticed some websites' facebook posts have a banner on their image.
Using NodeJs, I'm wondering what would be the most elegant way to proceed.(ie. Something better than a photoshop action or a PHP script running elsewhere). I guess cropping the image to the right format and adding an overlay PNG with ImageMagik would be viable opion. Are you aware of online services providing this simple functionality?
Since this resource is rarely refreshed from FB, I would not store it on disk and generate it on the fly.
In ImageMagick, you can create a banner image using -annotate and composite over your image. For example starting with your image, suppose I want to put a similar banner at the top. I create a semi-transparent background color image of a desired width to match your image and desired height and pointsize. Then I composite it at the top of your image.
convert UT-copy-social.png.jpeg \
\( -size 1200x90 xc:"rgba(255,0,0,0.5)" -font Arial -pointsize 64 \
-fill white -gravity east -annotate +50+0 "TEST" \) \
-gravity north -compose over -composite result.jpg
If you want a semi-transparent gradient banner, then modify it as follows:
convert UT-copy-social.png.jpeg \
\( -size 90x1200 gradient:"rgba(255,0,0,0.5)-rgba(255,0,255,0.5)" \
-rotate 90 -font Arial -pointsize 64 -fill white \
-gravity east -annotate +50+0 "TEST" \) \
-gravity north -compose over -composite result2.jpg
You can also do it similarly with -draw or label:. See http://www.imagemagick.org/Usage/text/

How to change picture background color using ImageMagick?

I want to change my picture background color, This is my source http://cdn.mayike.com/emotion/img/attached/1/image/dt/20170916/18/20170916180007_833.png.
If I want to change the background color to another color, what should I do?
If I want to change the background color to transparent, what should I do?
I tried using convert aa.png -background '#0e0e0e' bb.png, but that doesn't work.
I do not think you will get a perfect result due to the fact that your image is not binary. Nevertheless in Imagemagick you have two choices. First you could just change all white to red:
convert 20170916180007_833.png.jpeg -fuzz 25% -fill red -opaque white -flatten result1.png
Or you can do a flood fill to just change the outer area:
convert 20170916180007_833.png.jpeg -fuzz 25% -fill none -draw "matte 0,0 floodfill" -background red -flatten result2.jpg
To apply any background color, first the program should know the edges and background.
The image you use doesn't do that.
Although your command is correct, it doesn't work since edges and background is not distinguished. So we use Masking first
First run this to get edges:
convert aa.png -bordercolor white -border 1x1 \
-alpha set -channel RGBA -fuzz 20% \
-fill none -floodfill +0+0 white \
-shave 1x1 aa.png
Now you'll get the edges saved in aa.png. At this point your background is transparent. Next run the background color change command:
convert aa.png -background blue -flatten bb.png
Now you'll have the expected result.
Output Final Image
Source:http://www.imagemagick.org/Usage/masking/#bg_remove
Usually -opaque, or -transparent, is all that's needed. But because the image is black & white, we need to isolate ROI to effect. I would recommend using the MVG draw commands.
If change to another color, what should I do?
convert 20170916180007_833.png \
-fill '#0e0e0e' -fuzz 20% \
-draw 'color 0,0 floodfill' \
output_color.png
If change to transparent, what should I do?
convert 20170916180007_833.png \
-fill 'transparent' -fuzz 20% \
-draw 'color 0,0 floodfill' \
output_transparent.png

imagemagick text as a hole on solid background

I am simply trying to create some text as image with IM.
I want the size of the image to be automatically adjusted to text length.
Also I need the background color to be a solid specified color (rgb 166,127,000 in this example), and text color to be "transparent". I mean text "as hole" on the background.
I could obtain it with the following command:
/opt/local/bin/convert \( -font /fonts/myFont.ttf -pointsize 25 -background none -fill 'rgb(166,127,000)' -gravity center +antialias label:'TEST' \) -channel a -separate +channel -negate -fill -alpha set -channel RGBA -fill none -opaque black -fill 'rgb(166,127,000)' -opaque white png:-
I am looking for a simpler way to do it. Also I am having problems with antialias and the text looks too bulky.
Thank You.

Resources