TCustomIvorySurface::Pixels

Provides a pointer to the pixels of a locked surface.

__property unsigned char* Pixels;

Description

Use Pixels to alter the surface pixel by pixel. This is the fastest way of changing a pixel on a surface. Pixels is the same as the following expression:

ScanLine[0]

Before you use the Pixels property, you must lock the surface by the Lock method. Never leave a surface locked for a long time. Always unlock it if you don't want to manipulate it.

Be very careful when you're manipulating the pixels of a surface. Do not overrun beyond the surface memory. The lines on a surface are usually not contiguous. In other words, the next line is not immediately after the previous one. So do not treat the surface as an array of pixels. Only a single line of the surface can be treated as an array of pixels.

Use the following formula to get a pointer to the pixel in the line Row and column Col:

Pixels + Row * Pitch + Col

Pitch is a property of the surface also, and it must be used together with the Pixels. Now here is a sample code that runs over each pixel of the surface and clears them all:

unsigned char* pix = Pixels;
int next_line = Pitch - Width;
for(int row = 0; row < Height; row++)
{
   int count = Width;
   while(count--) *pix++ = 0;
   pix += next_line;
}

This code runs faster than the one that uses the ScanLine property to calculate the beginning of the next line again and again. The GetScanLine member function that is called automatically whenever you refer to the ScanLine property is defined as follows:

void* __fastcall TCustomIvorySurface::GetScanLine(int Row) const
{
   if(Pixels == NULL) return NULL;
   return (void*)(Pixels + Row * Pitch);
}

So if you're a real hacker like me, you must use Pixels and Pitch instead of ScanLine. :-)

Still, there is an advantage of ScanLine: those image manipulating algorithms that were written in C++Builder 3.0 and are using the ScanLine property can be copy-and-pasted and reused in an Ivory Draw application.

Back to TCustomIvorySurface