Change in SetImageBackgroundColor in 6.4.9-0 beta

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
Post Reply
rmagick
Posts: 245
Joined: 2006-03-16T17:30:48-07:00
Location: Durham, NC, USA

Change in SetImageBackgroundColor in 6.4.9-0 beta

Post by rmagick »

RMagick creates a new image by caling AcquireImage, then calls SetImageBackgroundColor to set the background color. In 6.4.8 and earlier, if the background color is "none" then the alpha channel is activated. I notice that in the 6.4.9-0 beta the alpha channel is not activated and I have to activate it explicitly. Is this the expected behavior going forward? Is there a better way for me to do this?

RMagick converts "none" to a PixelPacket using QueryColorDatabase. In both 6.4.8 and 6.4.9-0 the returned pixel has the values {red=0, green=0, blue=0, opacity=65535}. Then it stores the pixel packet in the ImageInfo background_color field before calling AcquireImage and subsequently SetImageBackgroundColor.

I hope my written description is sufficient. I'm having a hard time reproducing the problem using convert. Please let me know if you need more info and I'll work up a reproduction in C. Thanks for your help.

Here's the identify output when I don't explicitly activate the alpha channel:

Code: Select all

Image: rmnone-6.4.9.miff
  Format: MIFF (Magick Image File Format)
  Class: DirectClass
  Geometry: 200x200+0+0
  Resolution: 72x72
  Print size: 2.77778x2.77778
  Units: Undefined
  Type: Bilevel
  Base type: Bilevel
  Endianess: Undefined
  Colorspace: RGB
  Depth: 16/1-bit
  Channel depth:
    gray: 1-bit
  Channel statistics:
    gray:
      min: 0 (0)
      max: 0 (0)
      mean: 0 (0)
      standard deviation: 0 (0)
      kurtosis: 0
      skewness: 0
  Histogram:
     40000: (    0,    0,    0) #000000000000 black
  Rendering intent: Undefined
  Interlace: None
  Background color: white
  Border color: rgb(223,223,223)
  Matte color: grey74
  Transparent color: black
  Page geometry: 200x200+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: None
  Orientation: Undefined
  Properties:
    create-date: 2009-01-31T21:35:15+00:00
    modify-date: 2009-01-31T21:33:54+00:00
    signature: dd046ccaee01de364ee5306b48d1dde4b8d06ba484eb66c2123f92f1211c30ad
  Artifacts:
    verbose: true
  Tainted: False
  Filesize: 235kb
  Number pixels: 39.1kb
  Version: ImageMagick 6.4.8-9 2009-01-24 Q16 http://www.imagemagick.org
Same program, except I activated the alpha channel before writing the image:

Code: Select all

Image: rmalpha.miff
  Format: MIFF (Magick Image File Format)
  Class: DirectClass
  Geometry: 200x200+0+0
  Resolution: 72x72
  Print size: 2.77778x2.77778
  Units: Undefined
  Type: Bilevel
  Base type: Bilevel
  Endianess: Undefined
  Colorspace: RGB
  Depth: 16/1-bit
  Channel depth:
    gray: 1-bit
    alpha: 1-bit
  Channel statistics:
    gray:
      min: 0 (0)
      max: 0 (0)
      mean: 0 (0)
      standard deviation: 0 (0)
      kurtosis: 0
      skewness: 0
    alpha:
      min: 0 (0)
      max: 0 (0)
      mean: 0 (0)
      standard deviation: 0 (0)
      kurtosis: 0
      skewness: 0
  Alpha: none   #0000000000000000
  Histogram:
     40000: (    0,    0,    0,    0) #0000000000000000 none
  Rendering intent: Undefined
  Interlace: None
  Background color: white
  Border color: rgba(223,223,223,1)
  Matte color: grey74
  Transparent color: none
  Page geometry: 200x200+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: None
  Orientation: Undefined
  Properties:
    create-date: 2009-01-31T21:42:15+00:00
    modify-date: 2009-01-31T21:42:15+00:00
    signature: ac2878215ad33205d1732578c89f25ededaad1b676911c540825bcf4baa42d9b
  Artifacts:
    verbose: true
  Tainted: False
  Filesize: 313kb
  Number pixels: 39.1kb
  Version: ImageMagick 6.4.8-9 2009-01-24 Q16 http://www.imagemagick.org
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Change in SetImageBackgroundColor in 6.4.9-0 beta

Post by magick »

We'll need to see a program to illustrate the problem. Our program shows the matte channel is activated for a background color of "none":

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <magick/MagickCore.h>

int main(int argc,char **argv)
{
  ExceptionInfo *exception;
  Image *image;
  ImageInfo *info;

  MagickCoreGenesis(argv[0],MagickFalse);
  puts(GetMagickVersion(NULL));
  exception = AcquireExceptionInfo();
  info = AcquireImageInfo();
  image= AcquireImage(info);
  (void) QueryColorDatabase("none",&image->background_color,exception);
  (void) SetImageBackgroundColor(image);
  (void) printf("matte is %d\n",image->matte);
  MagickCoreTerminus();
}
rmagick
Posts: 245
Joined: 2006-03-16T17:30:48-07:00
Location: Durham, NC, USA

Re: Change in SetImageBackgroundColor in 6.4.9-0 beta

Post by rmagick »

Your reproduction looks like what RMagick is doing. I'll get you something asap. Thanks!
rmagick
Posts: 245
Joined: 2006-03-16T17:30:48-07:00
Location: Durham, NC, USA

Re: Change in SetImageBackgroundColor in 6.4.9-0 beta

Post by rmagick »

My description was incomplete. Here's a reproduction. At 6.4.9 the following program prints:

Code: Select all

$ ./none
ImageMagick 6.4.9-0 2009-01-31 Q16 http://www.imagemagick.org
name is #000000000000
matte is 0
At 6.4.8 it prints

Code: Select all

$ ./none
ImageMagick 6.4.8-9 2009-01-24 Q16 http://www.imagemagick.org
name is #000000000000
matte is 1
I suspect some coding error on my part. I notice that my code to convert a PixelPacket to a MagickPixelPacket is based on SetMagickPixelPacket in mogrify-private.h in 6.4.8.

Thanks for your advice.

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <magick/MagickCore.h>

int main(int argc,char **argv)
{
  ExceptionInfo *exception;
  Image *image;
  ImageInfo *info;
  PixelPacket pp;
  MagickPixelPacket mpp;
  char name[MaxTextExtent];


  MagickCoreGenesis(argv[0],MagickFalse);
  puts(GetMagickVersion(NULL));
  exception = AcquireExceptionInfo();
  info = AcquireImageInfo();


  (void) QueryColorDatabase("none",&pp,exception);

  GetMagickPixelPacket(NULL, &mpp);
  mpp.red     = (MagickRealType) pp.red;
  mpp.green   = (MagickRealType) pp.green;
  mpp.blue    = (MagickRealType) pp.blue;
  mpp.opacity = (MagickRealType) (mpp.matte ? pp.opacity : OpaqueOpacity);
  mpp.index   = (MagickRealType) 0;
  (void) GetColorTuple(&mpp, MagickTrue, name);

  SetImageOption(info, "background", name);
  info->background_color = pp;
  printf("name is %s\n", name);

  image= AcquireImage(info);
  (void) SetImageBackgroundColor(image);
  (void) printf("matte is %d\n",image->matte);
  MagickCoreTerminus();
}
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Change in SetImageBackgroundColor in 6.4.9-0 beta

Post by magick »

The problem is related to your call to SetImageOption(). 6.4.9-0 options override the ImageInfo structure members. Initially, AcquireImage() sets the background color to info->background_color but its modified by the "background" option. Since your background option sets an opaque color (i.e. #000000000000) the image matte channel is off. If you remove the SetImageOption() call, it behaves as expected. Alternatively, set the "background" option to a transparent color such as rgba(0,0,0,0). Another option is to set the mpp.matte to true:

mpp.matte = MagickTrue;
rmagick
Posts: 245
Joined: 2006-03-16T17:30:48-07:00
Location: Durham, NC, USA

Re: Change in SetImageBackgroundColor in 6.4.9-0 beta

Post by rmagick »

Thanks! I'll fix it.

Another good reason to try the betas!
Post Reply