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

Message ListMessage List     Post MessagePost Message

  Problem using patternColor
Posted by Ian Hammond on May-11-2018 23:34
Hi Peter,

Reference my Transparent issues, I chose to adopt your suggestion of using patternColor for the chart background. All I get is a series of random dots as my background. I have copied the section of my background image into a CImage and used GetPixel to extract the pixels from the image into a 1D array thus:


void Gadget::getPixelArray(CImage * pImage)
{
COLORREF PixelColour;

int iHeight = pImage->GetHeight();
int iWidth = pImage->GetWidth();


// Create array based on size of image
m_piPixelArray = new int[iWidth * iHeight];
m_iPixelArraySize = iWidth * iHeight;

for (int x = 0; x < iWidth; x++)
for (int y = 0; y < iHeight; y++)
{
PixelColour = pImage->GetPixel(x,y);
m_piPixelArray[x*iHeight + y]] = getChartColour(PixelColour);
}

}

In my Chart function, I have the following code:

c->setBackground(c->patternColor(IntArray(pixelArray, iPixelArraySize),
                                                                                                     sizeH, 0, 0));
c->setPlotArea(iPlotX, iPlotY, iPlotRadius, Chart::Transparent);

Could you please tell me if I have extracted the pixels in the correct order and if I have used the patternColor correctly.

Many thanks

  Re: Problem using patternColor
Posted by Peter Kwan on May-12-2018 23:26
Hi Ian,

If what you have is a CImage, you may consider the following method, which very short and is usually faster than using GetPixel (unless the image only have a few pixels such as less than 10000 pixels).

pImage->Save("temp.png");
c->setBgImage("temp.png");

Hope this can help.

Regards
Peter Kwan

  Re: Problem using patternColor
Posted by Ian Hammond on May-13-2018 19:26
Hi Peter,

Many thanks for your advice.

I did use the patternColor to load a png file and this did actually seem faster than the the GetPixel Method. As this will be part of a real-time display I was concerned about the overheads of redrawing the chart and loading a bg image.
Regards

  Re: Problem using patternColor
Posted by Peter Kwan on May-14-2018 16:44
Hi Ian,

The GetPixel itself is not fast - it needs to switch device context to get a pixel, get the pixel, convert it to RGB format, then restore the device context. And if the code calls it a large number of time, it can be quite slow.

Are your background image static? If the image is static, you only need to convert it to the color array once, so it should not affect performance. The modern Windows file system is also quite fast.

The following is the fastest method to obtain the color array, but it needs some background knowledge in bitmap to write the code:

First, you need to make sure the CImage is a DIB bitmap in RGB format with 8 bit per pixel. It depends on how you create the CImage in the first place. If it is not in this format, you can use CImage::CreateEx to obtain one in this format.

You can then use CImage::GetBits to get all the pixels at once, then copy the pixels one by one to the color array. When copying, remember to respect the row pitch (CImage::GetPitch) of the CImage, and convert the Windows RGB (which is actually BGR) to the ChartDirector RGB color.

Regards
Peter Kwan

  Re: Problem using patternColor
Posted by Ian Hammond on May-24-2018 01:26
Hi Peter,

Thanks for the advice. I went with the solution suggested using the GetBits and stripping out the individual colours and rebuilding them in the appropriate order. I am trying to ddo the same for the AngularMeter. Can you please tell me if I can make the inner part of the meter transparent but showing the rings that I have drawn.

Many thanks

  Re: Problem using patternColor
Posted by Peter Kwan on May-25-2018 03:14
Hi Ian,

For an AngularMeter, if the background is Chart.Transparent, and the "scale background" is transparent, then the "inner part" if the meter is transparent. For example:

AngularMeter *m = new AngularMeter(300, 180, Chart::Transparent);
m->setMeter(150, 150, 128, -90, 90);
m->addScaleBackground(148, Chart::Transparent, 10, 0xcccccc);

You mentioned that "I am trying to do the same for the AngularMeter." Do you mean you want to get the individual colors of the pixels in the AngularMeter? This should not be necessary if what you want is to use the meter as the background or foreground of another ChartDirector object. (You can use DrawArea.merge.) If you really want to color of individual pixels, there are several methods:

(a) Use DrawArea.getPixel to get the color of individual pixel. For example:

DrawArea *d = m->makeChart();
int color = d->getPixel(1, 3);

(b) Ask ChartDirector to output all pixels at once, then read the pixels. ChartDirector can output the pixels in BMP format (BaseChart.makeChart), which is essentially the same format as GetBits. However, the BMP standard does not support transparency. (Certain image standards, such as BMP and JPG, does not support transparency. The PNG standard supports transparency but is difficult for your code to decode.) One method to work around is to use a special color as the background color, such as 0x123456. Then in your code, when you see this color, just treat the pixel as transaprent.

Regards
Peter Kwan