I need to change each hue of yellow to blue, and each hue of dark gray to light gray in PNG images with transparency.
The problem is:
I can’t use Photoshop, because I have 100 images, and I need to change hues many time.
I can’t use Image Magick, because I need more sophisticated calculations, than ‘-fx’ can do.
I can’t use PHP imagefrompng(), because this nasty crap not works with a lot of my images,
even with all suggested fixes like:
$background = imagecolorallocate($png, 255, 255, 255);
// removing the black from the placeholder
imagecolortransparent($png, $background);
// turning off alpha blending (to ensure alpha channel information is preserved, rather than removed (blending with the rest of the image in the form of black))
imagealphablending($png, true);
// turning on alpha channel information saving (to ensure the full range of transparency is preserved)
imagesavealpha($png, true);
and so on. It works with some images, but not with others.
All I need is a PNG library (maybe not in PHP), that can give me red, green, blue and alpha component of a pixel at coordinates x, y, and then set this pixel after my calculations, eg:
$rgba = getrgba($image, $x, $y);
$rgba = my_function($rgba);
setrgba($image, $x, $y, $rgba);
Maybe you can suggest libraries in other languages, not only PHP?
2
Answers
If you don’t mind using Python check out Pillow, specifically its PixelAccess class. These threads (1, 2) should be helpful and have some code examples.
Method 1
If you just want to get at the raw pixel values of R,G,B and Alpha without worrying about compression and encoding, use ImageMagick to convert your image to plain, uncompressed, unencoded binary and read it and process it to your heart’s content.
So, if we make a 1×1 pixel PNG file with RGBA(0,64,255,0.5) to test with:
Now we can get ImageMagick to make a raw, RGBA file that you can read and process as you wish with whatever language you wish at whatever level of complexity that you wish:
and now we can look in that file:
Result
There you can see and read all the RGBA pixels. When you are finished, just do the opposite to get back a PNG – note that you must tell ImageMagick the size first since it cannot know this:
Note that ImageMagick is quite a large package to install, and you can achieve much the same as the above with the much lighter-weight
vips
package:Method 2
Alternatively, if you want your data as uncompressed, human-readable ASCII, use the venerable NetPBM formats of
PPM
(Portable Pixmap) andPGM
(Portable Greymap) – see NetPBM on Wikipedia.Make a 4×1 image and write as PPM:
You can see the 4 repeated RGB values there hopefully. If you want it as a file, just change the
ppm:-
at the end withsomeFile.ppm
.Make same image again and extract Alpha channel to separate file:
Hopefully you can see that
6554
is0.1
on a scale of 0-65535.If you just want 8-bit data on any of the above, add in
-depth 8
.Method 3
As Glenn suggests in the comments, another option is to omit the
-compress none
on Option 2 which will give you a very similar file format except the pixel data will be in binary, after the header which remains in ASCII. This is generally faster and smaller.