Change Image Color

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
rhinst

Change Image Color

Post by rhinst »

Hi,

I've got a bunch of .eps files, each containing a clip art image in solid black. I have a web application that needs to be able to convert one of these images from black to an arbitrary color on the fly and return it. I've attempted to accomplish this conversion using the following command:

Code: Select all

convert clip1.eps -opaque '#000000' -fill '#ff0000' clip1.png
I've also tried it with -fuzz "20%" just in case, but it's not doing anything. Can someone tell me where I'm going wrong, or at least point me in the right direction?

Thanks,

Rob
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Post by Bonzo »

Try swapping the -fill and -opaque

Are you using php ? If so this worked for me

Code: Select all

<?php
exec("/usr/local/bin/convert image.png -fill rgb\(255,0,0\) -opaque rgb\(170,170,170\) newimage.png");  
?
rhinst

Post by rhinst »

Thanks for the tip, but no luck with that...

I reversed the order of the -fill and -opaque arguments, and a weird thing happened. The black foreground color stayed the same, and the white background turned to a cyan color. What's that all about?

Could this be something to do with the fact that it's an .eps file? I'll try converting to a .png without modifying the colors first, then i'll run a second command to change the colors and see if it has any effect.
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Post by Bonzo »

It may be due to your file being an eps - I do not know what that is as I have never used one !

My example code uses rgb colours and you need to change those.
255, 0, 0 is a red & 170, 170, 170 is a grey colour

If you still have a -fuzz it may have been enough to select the white.

Change the rgb\(170,170,170\) to rgb\(0,0,0\)
rhinst

Post by rhinst »

Changing to a .png and then converting did the trick, but not as nicely as i would have hoped. I'm going to play around with fuzz a little bit and see if that yields better results.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Post by anthony »

The -opaque operator replaces a specific (or near if -fuzz is added) color to the previously set -fill color.

This however will not preserve any anti-aliasing that you may have in your image, so you will get aliased, or staircased edges to the recolored edges, and may also leave a halo of the original color around the shapes. That will be fine for GIF shapes, but not for anything else.

The better way is to do gradient recolors..
http://www.cit.gu.edu.au/~anthony/graph ... or/#linear
or gradient Lookup Tables
http://www.cit.gu.edu.au/~anthony/graph ... r/#recolor

However as you are just whating the shape, I gather you are wanting the backgroudn transparent. Then a black on white shpe is best used as a mask.

For example. This converts greyscale image into a colored shape image. The -negate inverse it into a mask image with white being transparent.

Code: Select all

   convert image.png -negate \
         +clone +matte -compose CopyOpacity  -composite \
         -fill red -colorize 100%    colored_shape.png
This will preserve the anti-aliased edges as semi-transparent pixels.
See using Image Masks...
http://www.cit.gu.edu.au/~anthony/graph ... els/#masks
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
rhinst

Post by rhinst »

Thanks Anthony, I used the gradient lookup table method and it worked perfectly. I still have one problem, however. The transparency in the background of the .eps file is not being preserved when I convert my .eps file to a .png file.

I've tried a number of different suggestions from people on the mailing list, but so far nobody has offered anything that has solved the problem. Is there anything special I need to be doing?

Thanks again.
rhinst

Post by rhinst »

Here's a little more info. I opened the .eps file in Photoshop and did "save for web" and saved it as a PNG-24. Then I ran "identify -verbose" on the resulting .png file and here's what the output looks like:

Format: PNG (Portable Network Graphics)
Geometry: 452x357
Class: DirectClass
Colorspace: RGB
Type: PaletteMatte
Depth: 8 bits
Endianess: Undefined
Channel depth:
Red: 8-bits
Green: 4-bits
Blue: 8-bits
Opacity: 8-bits
Channel statistics:
Red:
Min: 33
Max: 255
Mean: 187.016
Standard deviation: 102.326
Green:
Min: 17
Max: 255
Mean: 182.117
Standard deviation: 109.701
Blue:
Min: 38
Max: 255
Mean: 188.547
Standard deviation: 100.022
Opacity:
Min: 0
Max: 255
Mean: 186.264
Standard deviation: 109.385
Opacity: (255,255,255,255) #FFFFFFFF
Colors: 17
...

Then I tried converting the .eps to a .png using imagemagick, using a variety of different commands and comparing the results. The closest I could come was with this command line:

convert -type PaletteMatte image1.eps image1.png

This results in the following:
Format: PNG (Portable Network Graphics)
Geometry: 452x357
Class: PseudoClass
Colorspace: RGB
Type: GrayscaleMatte
Depth: 4 bits
Endianess: Undefined
Channel depth:
Red: 4-bits
Green: 4-bits
Blue: 4-bits
Opacity: 1-bits
Channel statistics:
Red:
Min: 0
Max: 15
Mean: 11.0453
Standard deviation: 6.37936
Green:
Min: 0
Max: 15
Mean: 11.0453
Standard deviation: 6.37936
Blue:
Min: 0
Max: 15
Mean: 11.0453
Standard deviation: 6.37936
Opacity:
Min: 0
Max: 0
Mean: 0
Standard deviation: 0
Colors: 256
...



I tried adding -depth 8 and it doesn't change anything. Any thoughts?
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Post by anthony »

If you are wanting the shape, don't worry about the transparency from the EPS, just use it as a greyscale mask to generate a colored shape.

Otherwise you need to do a few things as detailed in 'Postscript Text Handling'
http://www.cit.gu.edu.au/~anthony/graph ... postscript

First make sure you have a ""%%LanguageLevel: 3" comment line in the postscript EPS header.
Second use -channel RGBA.

I don't recomend this as some postscript generators use 'white' to rubout parts of an image.
better to use a greyscale mask instead.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
rhinst

Post by rhinst »

Anthony,

Thanks for the fast response. Forgive my ignorance, but I'm not sure what you mean when you talk about just wanting the shape.

Basically, this is what I'm trying to accomplish. I have a directory of .eps clip art files. I have a program that is taking arbitrary user-selected images from here and resizing them, changing the color, and converting to a raster format which can then be included in an SVG document. Since the clip art images can be overlapping, it's important that the transparent parts of each image are preserved.

The first step the program takes is to convert the clipart from a .eps file into a grayscale .png file. Using this command:

Code: Select all

convert clip1.eps -colorspace gray -resize 200x200 newclip.png
Then I do a gradient table lookup to color the clip art with the user-specified color:

Code: Select all

convert -colorspace RGB -size 10x100 gradient:#ff0000-#ffffff gradient.png
convert newclip.png gradient.png -fx 'v.p{0,u*v.h}' finalclip.png
All of this works perfectly, except that the transparent regions of the .eps files become opaque white, and thus each subsequent clip art image covers whatever images are below it instead of having see-through portions.


I hope all of that was clear.
rhinst

Post by rhinst »

Also, just to clarify one point, I can't just take all the clip art images that will appear in the SVG document and combine them into a single image to be included in the SVG. There are other elements in the document (text, shapes, etc..) which might appear over and under the clip art images. Each clip art image needs to be a separate standalone image.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Post by anthony »

So what do the PNG images look like. Just black and white, no transparency, or black and white with thrasnparency?

You are not being clear!

how about a link to an example EPS file?
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
rhinst

Post by rhinst »

The PNG file that results after the first call to convert is black and white with no transparency.
rhinst

Post by rhinst »

User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Post by anthony »

First look. I am suprised you get anything at all!!! normal document viewers show nothing on the eps. Amasingally IM extarcts a 'car' from this file!

Second look, the file has junk binary at the start of it!
Thrid the Language leven line in the file is '1' needs to be 3 for transparency
and last I don't think it has transparency in the EPS! there are gaps between the 'inside' and the 'outside' of the image that would normally not exists if the image had a white interier.

All I can suggest is making all white parts transparent (Eg use it as a mask)

Hmmm strange this fails...

Code: Select all

convert ca_car.eps \( +clone \) +matte -compose CopyOpacity  -composite -fill black -colorize 100%   car_transparent.png
But this works

Code: Select all

convert ca_car.eps png:- | convert - -negate +matte \( +clone \) -compose CopyOpacity  -composite -fill black -colorize 100%  car_transparent.png
Both should give the same result! Cristy what do you think.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply