SetPixel() too slow?
-
Hi, I wasn't sure where to put this, but this seems the most appropriate place. I'm trying to load an image from a 2 Dimensional array into the main screen DC, like so.
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
SetPixel(imgDC, x, y, RGB(imgarray[x][y], imgarray[x][y], imgarray[x][y]));
}
}StretchBlt(hdc, 0,0, 640, 480, imgDC, 0, 0, width, height, SRCCOPY);
But this becomes too slow for my needs if the image if larger than about 256x256. I have also tried using do while loops, which were a fraction faster. Is there a better way to do this?
"Sir, I protest. I am NOT a merry man!"
-
Hi, I wasn't sure where to put this, but this seems the most appropriate place. I'm trying to load an image from a 2 Dimensional array into the main screen DC, like so.
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
SetPixel(imgDC, x, y, RGB(imgarray[x][y], imgarray[x][y], imgarray[x][y]));
}
}StretchBlt(hdc, 0,0, 640, 480, imgDC, 0, 0, width, height, SRCCOPY);
But this becomes too slow for my needs if the image if larger than about 256x256. I have also tried using do while loops, which were a fraction faster. Is there a better way to do this?
"Sir, I protest. I am NOT a merry man!"
There is an incredibly fast way of doing this... LockBits; the first time I needed to do something like this it took me a while to get the indexing right... but it pays off in the end. The MSDN page on it... http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx[^] A good example... http://blog.paranoidferret.com/index.php/2007/08/31/csharp-tutorial-convert-a-color-image-to-greyscale/[^]
Bitmap image = (Bitmap)oldimage.Clone();
BitmapData bmpData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
unsafe
{
byte* ptr = (byte*)bmpData.Scan0.ToPointer();
for (int Y = 0; Y < image.Height; Y++)
{
for (int X = 0; X < image.Width; X++)
{
// alter the colours here
*ptr++ = 0; // blue
*ptr++ = 0; // green
*ptr++ = 0; // red
}
ptr += bmpData.Stride - image.Width * 3;
}
}
image.UnlockBits(bmpData);*ptr++
is the current byte representing a 'sub-pixel' of the current pixel at image position [x, y]: the reason why the pointer is incremented three times. Hope this helps.Matthew Butler
-
There is an incredibly fast way of doing this... LockBits; the first time I needed to do something like this it took me a while to get the indexing right... but it pays off in the end. The MSDN page on it... http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx[^] A good example... http://blog.paranoidferret.com/index.php/2007/08/31/csharp-tutorial-convert-a-color-image-to-greyscale/[^]
Bitmap image = (Bitmap)oldimage.Clone();
BitmapData bmpData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
unsafe
{
byte* ptr = (byte*)bmpData.Scan0.ToPointer();
for (int Y = 0; Y < image.Height; Y++)
{
for (int X = 0; X < image.Width; X++)
{
// alter the colours here
*ptr++ = 0; // blue
*ptr++ = 0; // green
*ptr++ = 0; // red
}
ptr += bmpData.Stride - image.Width * 3;
}
}
image.UnlockBits(bmpData);*ptr++
is the current byte representing a 'sub-pixel' of the current pixel at image position [x, y]: the reason why the pointer is incremented three times. Hope this helps.Matthew Butler
Hi, thanks for your reply. Is there a way to set the pixels of a DDB with this? I had thought it was DIB only?
"Sir, I protest. I am NOT a merry man!"
-
Hi, thanks for your reply. Is there a way to set the pixels of a DDB with this? I had thought it was DIB only?
"Sir, I protest. I am NOT a merry man!"
Naturality wrote:
Is there a way to set the pixels of a DDB with this? I had thought it was DIB only?
LockBits is GDI+ and works great. In addition to that... With GDI, a DIBsection gives you a bitmap you can use like a DDB but with a pointer to the pixel bits array. See CreateDIBSection(). A DIBSection (like a GDI+ Bitmap object) is also more flexible than a DDB, since it can be created it with the same pixel format as your data and still be selected into into a memory DC that is not the same format as the screen. Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Naturality wrote:
Is there a way to set the pixels of a DDB with this? I had thought it was DIB only?
LockBits is GDI+ and works great. In addition to that... With GDI, a DIBsection gives you a bitmap you can use like a DDB but with a pointer to the pixel bits array. See CreateDIBSection(). A DIBSection (like a GDI+ Bitmap object) is also more flexible than a DDB, since it can be created it with the same pixel format as your data and still be selected into into a memory DC that is not the same format as the screen. Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
Thanks, I've been looking into it and it seems like it's the answer for me :-D
"Sir, I protest. I am NOT a merry man!"