Re: Bitmap <-> ArrayList of points

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Iwanow wrote:

Thank you for that hint. Up to now, I've been using... ArrayLists to
store my data.

ArrayList stores System::Object^ managed handles. If you add an integer value to an ArrayList, it wraps that value into a managed object. This is called boxing. The C++/CLI compiler automatically generates code that wraps your integer value into a garbage collected object. In the old MC++, you had to explicitly __box() them. Either way, this is a major performance penalty, and a waste of memory too. That's why I suggested using array<unsigned char>, or even List<unsigned char> (if you're programming in .NET 2.0). List has an overhead to array, but if used correctly, it's almost negligible. It's like the difference between char* and std::string.

I use Bitmap objects as sources of original images, and a destinations
after processing. I usually access them through either:
- bmp->GetPixel(x, y).GetBrightnes() or
- bmp->SetBixel(x, y, Color)
Both functions are called within 'for' loops mentioned in my first
post. Will they work faster with cli::array?

I'm pretty sure that grabbing a pointer to the raw image data would be many times faster than GetPixel. I don't know how GetPixel works, but it must do at least a multiplication and an addition (usually TopLeftPtr + x - y * BytesPerLine, assuming the image is upside down). This is many times slower than incrementing a pointer.

Even if you use array<unsigned char>, using the array syntax happens to be much slower for me than interior_ptr<unsigned char>. What I do is the following:

array<unsigned char> buffer = gcnew array<unsigned char>(width * height);
interior_ptr<unsigned short> ptr = &buffer[0];
while(/*...*/)
{
*ptr++ = /*...*/;
}

This trick alone made my code about twice as fast than using array syntax, like buffer[offset++].

I'm not familiar with the Bitmap class, but I know it has a way to lock its pixels and get a byte pointer to its raw underlying data. Here's an example:

http://vbforums.com/showthread.php?t=260903

I think the C# byte* is the same as the C++/CLI interior_ptr<unsigned char>.

I recommend that you research Bitmap::LockBits and BitmapData a bit:
http://msdn2.microsoft.com/en-us/library/system.drawing.imaging.bitmapdata.aspx

Note that if you do this, you must deal with the following:
- windows bitmaps are upside down
- the raw data depends on the bits per pixel value. There are 1, 4, 8, 16, 24, 32-bit images. You must decode the color data from the raw bits on your own (which is very easy with 8 and 24-bit images, a bit tricky with 16-bit images, but I refuse to work directly with 16-bit bitmap)
- each line begins on a DWORD boundary, so usually there are some padding bytes after the last pixel in each line. Here's how to calculate the number of bytes per line:
BytesPerLine = (Width * BitsPerPixel + 31) / 32 * 4 * Height;

Since images are upside down, the last line is in fact the first, and instead of incrementing the line pointer by BytesPerLine, you have to decrement it.

Note that I have very little .NET experience compared to unmanaged code. 99.99% of my code is native C++. You should really do your own benchmarking with your own algorithm, but you should get much better result with Bitmap::LockBits than with GetPixel.

Tom
.



Relevant Pages

  • Re: Very Large Bitmaps
    ... Find great Windows Forms articles in Windows Forms Tips and Tricks ... Answer those GDI+ questions with the GDI+ FAQ ... > spaces and 16-bit images etc without the horrible ambiguity and missing ... A bitmap is loaded and expanded to an uncompressed raster so 18000 * ...
    (microsoft.public.dotnet.framework.drawing)
  • Re: Finding Mona
    ... anomolies. ... We can see that even the tiniest bitmap image sticks out like a sore thumb. ... I made a specific hypothesis based on the nature of bitmap images. ... The techniques I listed included statistics. ...
    (talk.origins)
  • Re: Did you know
    ... over bitmap formats if the number of information points are less than ... the svg file in one icon. ... Now try putting that PNG icon at something approaching a usable resolution. ... It doesn't scale better than bitmap images. ...
    (comp.sys.mac.advocacy)
  • Re: Did you know
    ... over bitmap formats if the number of information points are less than in the bitmap. ... Imagine the difference when we have to put four different version of the svg file in one icon. ... Vector graphics scale better than raster graphics, so you don't need as many copies to handle the same range. ... Some kind of art suffers, but that can be solved by having several vector images for certain key sizes. ...
    (comp.sys.mac.advocacy)
  • Re: Alpha Blending Question
    ... > Blending, I have to use Images, drawing primitives on them, setting ... the GDI way, you need to: create elliptical region, create a bitmap with the ... destination DC, draw bitmap using AlphaBlend, draw ellipse with clear brush ... Graphics engine uses 32bit DIB and it's own routines to draw shapes ...
    (microsoft.public.win32.programmer.gdi)