Converting a bi-tonal to a color image..
Converting a bi-tonal to a color image..
I've read in a TIFF that is a bitonal compressed image and want to change the colors associated with the white and black, say make it green and blue.
To accomplish this I assume I first need to convert the two color image into a full RGB image.. but my attempts at changing the colorspace, changing the imagetype have so far failed to produce a non black-and-white image. The attributes of the image object change, but they don't cause any change in the underlying data... so when I write the image out as a PNG, I'm still getting a black and white image.
TransformImageColorSpace... no effect
SetImageType ... no effect
Is there a way that actually works? I've been able to use the core api just fine so far.. but this has me stumped.
To accomplish this I assume I first need to convert the two color image into a full RGB image.. but my attempts at changing the colorspace, changing the imagetype have so far failed to produce a non black-and-white image. The attributes of the image object change, but they don't cause any change in the underlying data... so when I write the image out as a PNG, I'm still getting a black and white image.
TransformImageColorSpace... no effect
SetImageType ... no effect
Is there a way that actually works? I've been able to use the core api just fine so far.. but this has me stumped.
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Converting a bi-tonal to a color image..
What version of IM are you using? If v7, have you used "-colorspace sRGB"? Exactly what command are you using? Please link to your image.
snibgo's IM pages: im.snibgo.com
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Converting a bi-tonal to a color image..
You do not need to make the images colorspace sRGB before converting black/white to blue/green. This works fine in IM 6.9.5.5 Q16 Mac OSX
Create test bilevel image:
change to blue/green:
see http://www.imagemagick.org/Usage/color_ ... vel-colors
Create test bilevel image:
Code: Select all
convert logo: -colorspace gray -type bilevel logo.tif
identify -verbose logo.tif
Image: logo.tif
Format: TIFF (Tagged Image File Format)
Mime type: image/tiff
Class: DirectClass
Geometry: 640x480+0+0
Units: PixelsPerInch
Type: Bilevel
Base type: Grayscale
Endianess: LSB
Colorspace: Gray
Depth: 8/1-bit
Channel depth:
gray: 1-bit
Code: Select all
convert logo.tif +level-colors blue,green logo_color.tif
identify -verbose logo_color.tif
Image: logo_color.tif
Format: TIFF (Tagged Image File Format)
Mime type: image/tiff
Class: DirectClass
Geometry: 640x480+0+0
Units: PixelsPerInch
Type: Palette
Base type: TrueColor
Endianess: LSB
Colorspace: sRGB
Depth: 8-bit
Channel depth:
red: 1-bit
green: 8-bit
blue: 1-bit
Re: Converting a bi-tonal to a color image..
I'm interfacing with the library via c/c++ function calls, not using command line tools.
I"m creating the image from a TIFF blob:
After this, the imageMagickImage attributes are:
Colorspace is RGBColorspace
Compression is still Group4 compression
Depth is 8
colors is 2
colormap[0] is blue=0, green=0, red=65535
colormap[1] is blue=0, green=65535, red=0
Taint is MagickTrue
I then convert the image into a blob again (a PNG blob in this case)
That PNG blob written to a file is still white/black, so despite the changes to the color table and all, I'm not getting the image to change.
I have also trid to use OpaquePaintImage:
Also to no avail, I"m still getting out a white/black PNG image.
I"m creating the image from a TIFF blob:
Code: Select all
#include "magick/MagickCore.h"
#include "magick/image.h"
Image* imgMagickImage; // an imagemagick image handle
ImageInfo* imgMagickInfo= AcquireImageInfo(); // the imagemagick image info object
ExceptionInfo* imgMagickException= AcquireExceptionInfo(); // where exception information is stored from calls
imgMagickImage = BlobToImage(imgMagickInfo, (void*) tiffBlob, (size_t)tiffSize, imgMagickException);
free(tiffBlob); // free up the memory created by malloc in ccittBlobToTiffBlob as it is now no longer needed
strcpy_s(imgMagickImage->magick,MaxTextExtent, "png" );
TransformImageColorspace( imgMagickImage, RGBColorspace); // <- this doesn't seem to convert the image
SetImageType( imgMagickImage, TrueColorType); // <- neither does this
// Change the values of the color table from white/black to input values red/green
// background is index 0 (which is RED in the sample TIFF data I'm using as input)
imgMagickImage->colormap[0].red = (MagickRealType)(bitonalTileIn->background_color.red *(QuantumRange/65535.0));
imgMagickImage->colormap[0].green = (MagickRealType)(bitonalTileIn->background_color.green *(QuantumRange/65535.0));
imgMagickImage->colormap[0].blue = (MagickRealType)(bitonalTileIn->background_color.blue *(QuantumRange/65535.0));
// foreground is index 1 (which is GREEN in the sample TIFF data I'm using as input)
imgMagickImage->colormap[1].red = (MagickRealType)(bitonalTileIn->foreground_color.red *(QuantumRange/65535.0));
imgMagickImage->colormap[1].green = (MagickRealType)(bitonalTileIn->foreground_color.green *(QuantumRange/65535.0));
imgMagickImage->colormap[1].blue = (MagickRealType)(bitonalTileIn->foreground_color.blue *(QuantumRange/65535.0));
Colorspace is RGBColorspace
Compression is still Group4 compression
Depth is 8
colors is 2
colormap[0] is blue=0, green=0, red=65535
colormap[1] is blue=0, green=65535, red=0
Taint is MagickTrue
I then convert the image into a blob again (a PNG blob in this case)
Code: Select all
unsigned char* pngBlob = NULL; // for storing the PNG blob created later (note: we need to free the blob ourselves)
size_t tiffSize_sizet = tiffSize; // needed to allow g++ on a linux to compile the ImageToBlob (unsigned int* doesn't convert to size_t* there)
pngBlob = ImageToBlob( imgMagickInfo, imgMagickImage, &tiffSize_sizet, imgMagickException); // create the PNG blob, based on the magick member (png)
I have also trid to use OpaquePaintImage:
Code: Select all
MagickPixelPacket origColor;
MagickPixelPacket newColor;
origColor.red = 0; // black
origColor.green = 0;
origColor.blue = 0;
newColor.red = (MagickRealType)(bitonalTileIn->background_color.red *(QuantumRange/65535.0)); // is red in background color
newColor.green = (MagickRealType)(bitonalTileIn->background_color.green *(QuantumRange/65535.0));
newColor.blue = (MagickRealType)(bitonalTileIn->background_color.blue *(QuantumRange/65535.0));
// newColor red=65535, green & blue=0
OpaquePaintImage( imgMagickImage, &origColor, &newColor, MagickFalse); // should replace all black with red color
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Converting a bi-tonal to a color image..
Until you convert black/white to other colors, IM will recognize that it is grayscale (or bilevel) and keep it that way. IM does not allow grayscale to be convert to color unless it has actual color in it. Only a few formats permit that with a -define. See http://www.imagemagick.org/script/comma ... php#define for -define colorspace:auto-grayscale=on|off.
I do not use any API and so do not know what features they support.
I do not use any API and so do not know what features they support.
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Converting a bi-tonal to a color image..
I know nothing about colormaps, but I can't see anything in your code that tells the image to use colormaps, or how many entries there should be, and so on.
The function LevelColorsImage() is the obvious way of doing this.
The function LevelColorsImage() is the obvious way of doing this.
snibgo's IM pages: im.snibgo.com
Re: Converting a bi-tonal to a color image..
When it reads the bitonal TIFF it already has a color map - one entry is black and one is white. Maybe my confusion is with misleading information in attributes of the imagemagick image structure that don't apply to the actual pixel payload.
So the question then is HOW does one convert the bilevel to color. Thats step one of the two step sequence:
1) Convert from Bilevel to Color
2) Change the colors from white->red and black->green (for this example).
Raster image has one of two encodings: either
1) The image pixel data contains a color table reference and the that entry in the color table is the (say) RGB value to use.
or
2) The image pixel data is itself an (say) RGB value.
If the bitonal image is has a color table based encoding, then all I'd have to do is change the definitions of the colors to recolor.
If the bitonal has the color stored as the pixel data, then I'd have to touch the pixels to change their color.
Everything I saw about the image structure indicated to me the image was stored as a compressed raster with a color table of 2 entries for bitonal.
My attempts to make it become an RGB image via the core documentation has not led to success.
Nor has my attempt to paint the pixels with new colors.
The documentation at http://www.imagemagick.org/script/magick-core.php doesn't give a lot of colormap functionality; a grey colormap is the starting point.
So the question then is HOW does one convert the bilevel to color. Thats step one of the two step sequence:
1) Convert from Bilevel to Color
2) Change the colors from white->red and black->green (for this example).
Raster image has one of two encodings: either
1) The image pixel data contains a color table reference and the that entry in the color table is the (say) RGB value to use.
or
2) The image pixel data is itself an (say) RGB value.
If the bitonal image is has a color table based encoding, then all I'd have to do is change the definitions of the colors to recolor.
If the bitonal has the color stored as the pixel data, then I'd have to touch the pixels to change their color.
Everything I saw about the image structure indicated to me the image was stored as a compressed raster with a color table of 2 entries for bitonal.
My attempts to make it become an RGB image via the core documentation has not led to success.
Nor has my attempt to paint the pixels with new colors.
The documentation at http://www.imagemagick.org/script/magick-core.php doesn't give a lot of colormap functionality; a grey colormap is the starting point.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Converting a bi-tonal to a color image..
You can skip step one, since IM won't generally allow that. All you need do is change the colors and IM will automatically promote the type to color and the colorspace to sRGBSo the question then is HOW does one convert the bilevel to color. Thats step one of the two step sequence:
1) Convert from Bilevel to Color
2) Change the colors from white->red and black->green (for this example).
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Converting a bi-tonal to a color image..
Does it? Which part of your code finds that?When it reads the bitonal TIFF it already has a color map - one entry is black and one is white.
I expect you can do this with palettes, if you really want to. I would just SetNoPalette() to ensure it doesn't have a palete, then LevelColorsImage().
You still haven't told us the version of IM you are using.
snibgo's IM pages: im.snibgo.com
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Converting a bi-tonal to a color image..
Also what platform?snibgo wrote:You still haven't told us the version of IM you are using.
Re: Converting a bi-tonal to a color image..
Thanks for the tips. At present I'm using ImageMagick 6.8.9-0 Q16 x86 compiled into static library files on a Windows 7 platform with Visual Studio 2010. I intend to upgrade to 6.9.5-5 or 7.0.2-7 at some point. I'd think these sort of basic image manipulation features would be working in 6.8.x however.
I'll try just changing the colors; my attempts to do so via via:
has so far resulted in no change to the output PNG generated subsequently by: (its still a white/black image)
I'll try just changing the colors; my attempts to do so via via:
Code: Select all
MagickPixelPacket origColor;
MagickPixelPacket newColor;
origColor.red = 0;
origColor.green = 0;
origColor.blue = 0;
newColor.red = QuantumRange;
newColor.green = 0;
newColor.blue = 0;
if (OpaquePaintImage( imgMagickImage, &origColor, &newColor, MagickFalse) == MagickFalse) {
std::cerr << "ERROR: BitonalTile: OpaquePaintImage() ImageMagick call returned false." << std::endl;
}
Code: Select all
std::stringstream pngNameS;
pngNameS << imageFilePrefix << imageCounter << "_magick.png";
strcpy_s(imgMagickImage->filename, MaxTextExtent, pngNameS.str().c_str() );
std::cout << "DEBUG: Writing ImageMagick image to PNG file [" << pngNameS.str() << "]" << std::endl;
WriteImage(imgMagickInfo, imgMagickImage);
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Converting a bi-tonal to a color image..
As user snibgo said above
"The function LevelColorsImage() is the obvious way of doing this."
It assumes you are starting with black and white and replace black with one color and white with the other color that you specify.
See http://www.imagemagick.org/script/comma ... vel-colors
"The function LevelColorsImage() is the obvious way of doing this."
It assumes you are starting with black and white and replace black with one color and white with the other color that you specify.
See http://www.imagemagick.org/script/comma ... vel-colors
Re: Converting a bi-tonal to a color image..
When I'm looking at the image structure in the debugger, I can see the various attributes of the structure, one of which is called colormap that has 2 entries in the array at index 0, and 1, with values for black(0,0,0) and white (65535,65535,65535).. but as I was trying a bunch of things, I backtracked to see what was actually causing the changes.snibgo wrote:Does it? Which part of your code finds that?When it reads the bitonal TIFF it already has a color map - one entry is black and one is white.
I expect you can do this with palettes, if you really want to. I would just SetNoPalette() to ensure it doesn't have a palete, then LevelColorsImage().
You still haven't told us the version of IM you are using.
Attempting to affect the colormap with TransformImageColorspace( imgMagickImage, RGBColorspace); or SetImageType( imgMagickImage, TrueColorType); resulted in no changes to the underlying colormap attribute, it stayed null (ie undefined).
It was the writing out of the image as a PNG via
Code: Select all
strcpy_s(imgMagickImage->filename, MaxTextExtent, "outputimage.png" );
WriteImage(imgMagickInfo, imgMagickImage);
I'd rather not go through the needless exercise of generating an png file, as I don't really need to produce a file, I need the png blob for further usage. So I am trying to find a way to take the existing image in memory, and recolor it. Easiest is if its indexed-color, because then I only need to change the color map, vs touching the individual pixels to recolor.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Converting a bi-tonal to a color image..
You cannot access nor change the colormap directly in Imagemagick. Please try LevelColorsImage() whether you write out to a file or keep as a blob.
Re: Converting a bi-tonal to a color image..
After some fiddling around with LevelColorsImage() as the documentation language was a big unclear to me, I found the combination:
That indeed maps the image's black color to red, and its white color to green.
Specify what color you want black mapped to and white mapped to and set the flag to TRUE.
Thank you so much all for the assistance.
Final followup question - I was in this bind somewhat as I wasn't able to discover this solution directly be looking over the API as described in :
http://www.imagemagick.org/script/magick-core.php (cannot find LevelColorsImage, much less guess where that might be in the bullet list if it was in there)
Is there a source that documents the core API that gets maintained with the code?
Or does one just poke around the source .c files and read the function descriptors?
Code: Select all
foreColor.red = QuantumRange;
foreColor.green = 0;
foreColor.blue = 0;
backColor.red = 0;
backColor.green = QuantumRange;
backColor.blue = 0;
LevelColorsImage( imgMagickImage, &foreColor, &backColor, MagickTrue);
Specify what color you want black mapped to and white mapped to and set the flag to TRUE.
Thank you so much all for the assistance.
Final followup question - I was in this bind somewhat as I wasn't able to discover this solution directly be looking over the API as described in :
http://www.imagemagick.org/script/magick-core.php (cannot find LevelColorsImage, much less guess where that might be in the bullet list if it was in there)
Is there a source that documents the core API that gets maintained with the code?
Or does one just poke around the source .c files and read the function descriptors?