Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Effective update of Image->Canvas ? 1

Status
Not open for further replies.

acp32

Technical User
Nov 14, 2002
6
GB
I am looking for a method of updating an Image rapidly from data stored in a 2D matrix. I currently use the following code for each pixel:
Image1->Canvas->Pixels[x][y] = greyscale;

My image is a 512x512 array so the above line is part of an embedded for loop that iterates 262,144 times to display the whole image.

Surely there is a more efficient way of getting data in one block to an image, as opposed to doing it one pixel at a time?

Any recommendations?
Thanks in advance.
 
Show more code. For instance, what is the greyscale value? Is this database you're pulling the images from changing while you display it? Or will it be fairly static?

Perhaps instead of using Image1, use a buffer that only gets set one time when the data has changed. So if your 2D Matrix changes, update the buffer. Then copy the buffer to your image. If the matrix doesn't change, don't do anything.

Chris
 
The data source is a CCD camera, which generates a stream of 262144 data values. This is to cover a 512x512 pixel source. I'm trying to view the camera image on the GUI as fast as possible.
I've created an Image1 on the GUI (width 512,height 512).
I update the image pixel by pixel using the following code.

unsigned char pixel;
int bytecount = 0;
for (y=0;y<512;y++)
{
for(x=0;x<512;x++)
{
pixel = cameradata[bytecount];
bytecount++;
Image1->Canvas->Pixels[x][y] = (pixel*65536)+(pixel*256)+pixel;
}
}

The (pixel*65536)+(pixel*256)+pixel expression is a method of converting an 8bit value into the enum TColor suitable with the Pixels property.
Is there a method of updating the Image in one block, as opposed to pixel by pixel?
 
Is this thread of any help ?

thread101-485323
 
ScanLine returns an array of pixels.
You could copy this array with memcpy
 
I don't think ScanLine will help me.
If there was a function that allowed me to write a line at a time that would certainly help.
The image I want to get onto the canvas is not in a bitmap format. I don't know if there is any benefit in converting the data into a bitmap first and loading that?
 
Hmm...first problem is speed. That's a lot of updating. I don't know what kind of hardware you have or if it would handle it.

I think saving the data to a bitmap file each time and then reloading that file is going to be too much overhead. The best approach would be to find a way to load the bitmap directly from memory all at one time.

There's a function for TBitmap called LoadFromStream. This might work if you are saving it to a stream. How are you loading cameradata[]? Are you reading a hardware memory from the camera or is it streaming in on a serial port or something?

If you are setting cameradata[] yourself, then you just need to add the header bytes for the bitmap to a static part of cameradata, then only update the image bytes. Then save it as a stream.

i.e.
unsigned char headers[20];
unsigned int cameradata[512][512];

headers[0] = 0;
headers[1] = 2;
etc...
I don't know what the standard bitmap header definition is or how long it is. You would have to look that up.

// Perform these two only one time during creation.
TStream *Bitmap = new TStream();
Bitmap->Size = 512*512 + 20;


Bitmap->WriteBuffer(headers, 20);
Bitmap->WriteBuffer(cameradata, 512*512); // Replace 512*512 with a constant, so it won't recalc it everytime.

Image1->Picture->Bitmap->LoadFromStream(Bitmap);
Image1->Repaint(); // Might not want this in there.

Good luck,
Chris
 
Thanks for your suggestions. I've got it working. Here is the essential code.
Code:
//Define parameters
TMemoryStream* Bitmap = new TMemoryStream();
unsigned char header[54];
unsigned char cameradata[262144];
unsigned char imagebtmp[786432];

//Create header & test data
//The header is 54 bytes long with the following fields
//Field         Bytes   Description
//bfType        2       Bitmap identifier. Must be 'BM'
//bfSize        4       Can be set to 0 for uncompressed bitmaps
//bfReserved    2       Set to 0
//bfReserved    2       Set to 0
//bfOffbits     4       Specifies start of image data in bytes
//biSize        4       Size of info header (40 bytes)
//biWidth       4       width of bitmap in pixels
//biHeight      4       height of bitmap in pixels
//biPlances     2       Set to 1
//biBitCount    2       Bit depth of bitmap, set to 24
//biCompression 4       Images are uncompressed so set to 0
//biSizeImage   4       The size of the padded image in bytes
//biXPelsPerM   4       Resolution in X, set to 0
//biYPelsPerM   4       Resolution in y, set to 0
//biClrUsed     4       N/A, set to 0
//biClrImportant4       N/A, set to 0
    for (int i=0;i<54;i++)
   { header[i] = 0; }
   header[0] = 66;      //Set to 'B'
   header[1] = 77;      //Set to 'M'
   header[10] = 54;     //Sets bfOffbits
   header[14] = 40;     //Sets biSize
   header[19] = 2;      //sets biWidth to 512
   header[23] = 2;      //sets biHeight to 512
   header[26] = 1;      //Sets biPlanes
   header[28] = 24;     //Sets biBitCount
   header[36] = 12;     //Sets size of padded image 512x512x3

   //Create some simulation data
   for (int i=0;i<262144;i++)
   {
      cameradata[i]=0;
   }

   //Convert the cameradata to the imagebtmp. Each 
   //8bit pixel value is repeated 3 times for the 
   //Red, Green, Blue to give us a greyscale
   int tally =0;
   for (int j=0;j<262144;j++)
   {
      imagebtmp[tally]=cameradata[j];
      tally++;
      imagebtmp[tally]=cameradata[j];
      tally++;
      imagebtmp[tally]=cameradata[j];
      tally++;
   }

//Now elsewhere in the code we can update image
   Bitmap->Clear();
   Bitmap->WriteBuffer(header,54);
   Bitmap->WriteBuffer(imagebtmp,786432);
   Bitmap->Position = 0;
   Image1->Picture->Bitmap->LoadFromStream(Bitmap);
   Image1->Refresh();

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top