ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Strange PNg Alpha Mask Behaviour
Posted by Andreas Lachner on Mar-01-2013 16:57
Attachments:
Hi,
we are considering to swap our existing image library to chartdirector.

I am running a code like this:

   DrawArea           *pDA;
   int                iPixelColor;

   pDA=new DrawArea();
   pDA->setSize(xNewSize,yNewSize,Chart::Transparent);
   pDA->setPaletteMode(2);
   pDA->setTransparentColor(-1);

   for (xloop=0;xloop<xNewSize;xloop++)
    for (yloop=0;yloop<yNewSize;yloop++)
    {
     iPixelColor=lpbOriginalRGB[yloop*xNewSize*3+(xloop*3)+2]+(lpbOriginalRGB[yloop*xNewSize*3+(xloop*3)+1]<<8)+(lpbOriginalRGB[yloop*xNewSize*3+(xloop*3)+0]<<16);

     if (lpbDataNew[yloop*xNewSize+xloop]==2)
      iPixelColor+=(0x00<<24);
     else
      iPixelColor+=(0xFE<<24);

     pDA->pixel(xloop,yNewSize-yloop-1,iPixelColor);
    }

   pDA->outPNG("alpha.png");
   delete pDA;
  }

Basically lpbOriginalRGB holds and image and lpbDataNew the result of a background segmentation.

If I set the maximum transparency to 0xFE all is fine. If I set it to 0xFF (which would be correct), I get strange artefacts in the border regions between the image and the background (see enclosed).

Would you have any idea what causes that or am I doing something wrong?

Thanks
0xfe Alpha.png
0xff Alpha.png

  Re: Strange PNg Alpha Mask Behaviour
Posted by Peter Kwan on Mar-02-2013 03:42
Hi Andreas,

In ChartDirector, the fully transparent color is 0xFF000000 (which is Chart::Transparent). All other colors of the form 0xFFRRGGBB will be treated as "dynamic colors" (like gradients, wallpaper patterns, etc). See:

http://www.advsofteng.com/doc/cdcpp.htm#colorspec.htm

The reason we use such a system is so that you can handle dynamic colors and normal colors in the same way (as a 32-bit integer).

So for you case, instead of "iPixelColor+=(0xFE<<24);", you may use "iPixelColor = Chart::Transparent;".

You may be aware that calling DrawArea.pixel for each pixel is inefficient if there are a huge number of pixels. For example, if the image is 1000 x 1000, the method will be called 1 million times. A faster method is to prepare the image in memory as an integer array 1000000 in size, then use it to create a "pattern color" (see DrawArea.patternColor), and use the patternColor to draw a rectangle on the DrawArea. It should be like:


int myColor = d->patternColor(IntArray(myArrayOfColors, xNewSize * yNewSize), yNewSize);
d->rect(0, 0, d->getWidth() - 1, d->getHeight() - 1, myColor, myColor);


Hope this can help.

Regards
Peter Kwan