Imagick: change hue of color range so it becomes different color - imagick

I'm writing a small open-source game and up to this point I've made all the graphics myself (yeah, that's hardcore, but that was the point).
Now using Imagick in image representing hero I'd like to replace the orange shirt which has few shades of orange with different color (so basically change its hue, but with appliance to only "orange" color). So the shirt becomes green (or any other color).
It's too much for me as I'm beginner with Imagick. How could I do it? Tried searching but no success.
Thanks for help to everyone willing to help!

I was able to solve it with this code:
convert input.png -fill "#00cccc" -fuzz 10%% -opaque rgb(255,127,38) output.png
Inspired by: https://stackoverflow.com/a/20976373/3107185

Related

How to change colors of an image using RGBA and more channels independently of their color

Since it is hard to me to explain what I'm trying to do, I'm gonna show you this page to show you what I'm trying to reproduce and understand:
https://optifine.net/showCape?colTop=FF0000&colBottom=00FF00&colText=0000FF&colShadow=FD0000
which outputs this:
and this one https://optifine.net/showCape?colTop=FF00FF&colBottom=0034EE&colText=000000&colShadow=FF00E2 outputs this:
You can modify the hexadecimal colors, basically I'm trying to reproduce something like that. Basically you modify the colors and it gives you an image at the end with the colors you used.
I've tried to make the "possible" template that could be used on the page on Photoshop which can be downloaded here, it is a .psd file, that's because of the Alpha Channel, which I'm not even sure if done correctly. But based of these RGBA channels it should be possible to change the color. Can be downloaded here: https://workupload.com/file/4xYkgQMk
So what I know so far is that there is a template with RGBA channel. Each channel is indepedent so it apperantly doesn't matter if it's RGBA and at the end R channel is used to turn into another color other than red, where I'm not sure about that.
I've asked the developer he told me that these channels get interpolated with the real color after that, probably the one you choose.
Basically what is happening at showCape? and its URL parameters is that, lets assume colTop got assigned to the red channel then when you put a color in colTop it will get a fixed color that it will encode or something.
So the template has 4 Channels RGBA that can be made in Photoshop, the white color 255,255,255 means basically full and the black 0,0,0 means complete black. Like that you can setup brightness scales for the template.
I just don't know how to modify the channels and I don't understand how to use the Alpha channels properly or set them up.
I'm also not sure in which programming languages it is possible to peform and if you can test the template directly in something like Photoshop. Is it possible to do it in JavaScript or something to easy setup and if not on what then, to test it fast?
Ok, so here's how you can generate that sort of thing with ImageMagick, which is included in most Linux distros and is available for macOS and Windows. Note that there are Python, PHP, node.js and other bindings available.
First, generate a red rectangle:
magick -size 200x150 xc:red red.png
Now see how to do the same thing with hex codes:
magick -size 200x150 xc:"#ff0000" red.png
Now, draw a red rectangle with a blue one on top:
magick -size 200x150 xc:red -fill blue -draw "rectangle 10,10 80,140" redandblue.png
Now make the blue transparent:
magick -size 200x150 xc:red -fill blue -draw "rectangle 10,10 80,140" -transparent blue redandtrans.png
Now make a gradient from lime green to magenta:
magick -size 200x150 gradient:lime-magenta gradient.png
Now overlay the red rectangle with transparent window onto the gradient:
magick gradient.png redandtrans.png -composite overlay.png
Now add text:
magick overlay.png -fill "#0000ff" -pointsize 16 -draw "text 90,40 'Coloured text'" result.png
And now do the whole thing again, in one go:
magick -size 200x150 gradient:lime-magenta \
\( xc:red -fill blue -draw "rectangle 10,10 80,140" -transparent blue \) \
-composite \
-fill "#0000ff" -pointsize 16 -draw "text 90,40 'Coloured text'" result.png
Now you have provided a template, I can separate out the channels with ImageMagick like this and append them side-by-side with Red channel on the left, then Green, then Blue then the alpha/transparency channel on the right. I also added a red box around each one so you can see the extent on StackOverflow's white background.
magick template.png -separate -scale 100x +append channels.png
Keywords: ImageMagick, absolute basics, tutorial, transparency, compose, overlay, command line, image processing.
this sounds like indexed colors / palette effect from the VGA days (like plasma, water and fire) Where you change the palette (in a specific way) and image changes with it.
The idea is that Your image/sprite does not contain RGB colors directly but color indexes from palette instead. Where part of the palette for your image/sprite contains a color gradient so gradients on image are also gradients on index (neighboring shades have also neighboring indexes). Many old pixelart sprites and images from the old days are done this way (sorted palette).
Now you can simply chose few colors in that part of palette and interpolate the rest of the gradient (linearly or better).
To mimic this your need:
have a indexed color pixel art with sorted palette
For example You can convert your image into BMP or GIF with palette and sort the colors.
detect the part of palette with color gradient
change/update the gradient
re-render or recolor image.

Imagemagick: Converting specified color leaves slight border

I'm trying to overlay a green image over another image, and then convert the green color to transparent. The code I use is below. It works okay, however it leaves a slight green border. What's the best way to have this green border not show up? I tried using fuzz, however results with this vary. Sometimes it cuts out other colors. Is there a better way to prevent the green border than using fuzz?
convert image.png ../greenoverlay.png -layers merge image.png;
convert image.png -fuzz 41% -transparent \#00FF00 final.png;
Thank you all!

Finding the Most Bold Color in a Picture

I have an array of Colors that represents a picture. I want to find the most bold / most standout color from that frame (aka a bright pink if there is no pink in the frame or a bright yellow if there is no yellow in the frame, etc). Currently I don't know how to do this efficiently. Is there any known or efficient way of doing this efficiently for a 1280 by 720 pixel image (921,600 pixels) or any method you can think of?
As a starting point, I would say you are looking for the most saturated colour, so I would suggest converting to HSL colorspace, discarding the Hue and Lightness and seeing which one has the highest saturation.
So, for a quick example using ImageMagick using these two images:
This is the command yo would run in Terminal:
convert lighthouse.png -colorspace hsl -separate -delete 0,2 saturation.png
And here are the results - the most saturated colours show up as white.

Image background removal algorithms

I've lots of images with a white background and I need to remove it (make it transparent). I've already tried imagemagick convert and for some image that worked quite well, but still cannot be used on dark background.
I'm kind a noob in this branch of programming... Someone know some good algorithms to remove the background?
Plus, would be great if it could correctly process an image like this:
http://dev.addvert.it/cache/24eeab00e5987452d09fbeec0c7678d6_w472_h472_sc.jpg
The problem with convert diff is it erase a lot of the image, while the border algo doesn't touch the central part.
I totally understand how hard is for a calculator to do something like this and I'm pretty amazed with the results of convert, but if there's the chance of a better solution, why not ask? :D
You are not constrained to converting white pixels to transparent. You could maybe take the colour of the top-left corner pixel and make all pixels that colour transparent and it will work for black backgrounds too:
As suggested by #emcconville, the first of the following two options is more succinct:
convert towel.jpg -fill none -fuzz 2% -draw 'matte 0,0 replace' output.png
or, per my original,
convert towel.jpg -alpha on -fill none -fuzz 5% -draw 'color 0,0 replace' output.png
You may find this more readable...
convert towel.jpg -fuzz 5% \
-transparent $(convert towel.jpg -format "%[pixel:p{0,0}]" info:) \
output.png
In the second line, $(convert ...) just gets the colour of the top-left pixel and feeds that into the middle of the outer convert command as the colour to make transparent - but it is only doing the same thing as the first version.

Crop a face/head using oval/polygonal shapes without using flash? (ajax or html5?)

My mission is to let users upload their own photos then the site crops the face+hair and pastes them on an ecard. The tough part is that I'm not allowed to use flash =/
I understand there are ajax or js face detection solutions out there, but what stumps me is how do I crop an odd shaped pattern. Imagemagick/graphicsmagick as I know can only crop a rectangular or square shaped object (please correct me if I'm wrong). Will this pretty much destroy the whole idea until im has the functionality to crop odd shapes? or are there other ways to crop circles or polygons?
An idea popped up to maybe allow the user to draw some lines in their photo for cropping then maybe the site converts the lines to a vector and fills a color around the lines, the colors are then converted by im to transparent... but then I have no idea how to start this one.. probably not possible at the moment (?).
I'm running out of ideas :(
I have just successfully created a crop :) although not perfect it should work in android or iphone/ipad.
Basically I used a js plotting tool to mark the coordinates, save all those coordinates somewhere.
Then use the coordinates for imagemagick, it appears that although IM doesn't really crop odd shapes it can however use 'mask' to convert the bg of the photo by combining the stencil (where we draw the lines using our coordinates, fill the bg with #000000 color) and the original photo.
The result should be the crop we are looking for :) now we added in some feathering since it's kinda edgy. All this using imagemagick.
Now all we needed are curvier lines since I used 'path' in IM which doesn't really offer a smooth crop. Someone suggested to use 'cubic curves' but may require additional coding since it needs some parameters for each coordinate.
This command will create our stencil (the long set of numbers are our coordinates):
convert -size 450x125 xc:black -fill white -stroke black -draw "path 'M +60+9 +94+18 +96+19 +84+27 +92+36 +97+43 +103+56 +102+58 +109+66 +109+74 +101+68 +98+76 +98+84 +95+88 +98+91 +106+95 +110+99 +111+103 +99+106 +89+108 +73+112 +56+109 +40+109 +26+103 +37+97 +46+91 +48+88 +39+80 +36+71 +32+78 +27+72 +30+61 +35+55 +42+41 +30+37 +40+24 +51+14 +156+9 +197+6 +236+8 +269+16 +265+36 +248+50 +222+52 +213+35 +198+24 +174+18 +155+13 +60+9'" stencil.gif
We will then combine the stencil with the original image (which should bring out our transparent 'crop'):
convert original.jpg stencil.gif -alpha off -compose CopyOpacity -composite combined.png
Finally we feather out the edges:
convert combined.png -alpha set -virtual-pixel transparent -channel A -blur 0x0.7 -level 50,100% +channel -background none -flatten final.png
This is how it works now : https://lh6.googleusercontent.com/_2lSoW37_zqo/TYCD65Vu4zI/AAAAAAAAEcc/vjlCPM54FTI/s800/theoryinpractice.jpg 
That's about it, I hope this helps someone.

Resources