The most important one is that Delphi has a very powerful method to work with image. The method called Scanline. For a brief explanation of this method, just read it here.
Once, a friend asked me about how to implement Delphi's ScanLine when working in .NET. Hmm... that's new to me. As far as I now, there is no such method which have same ability with Delphi's ScanLine. Common methods used to work with Image (specifically Bitmap) is Bitmap.GetPixel and Bitmap.SetPixel method. But these methods are extremely slow to be used when working with a huge image.
After browsing through uncle Google for a while, I found out that there is a method which can be used when we want to work directly accessing image data in memory. The method is Lockbits. Please refer to this article for the explanation. The writer has just explain the method in very detail and good way, so I believe you'll understand quickly.
Here is an example to do a Grayscale operation with Bitmap.GetPixel and Bitmap.SetPixel method.
///
/// Grayscale method
///
public void Grayscale()
{
int width = _bmp.Size.Width;
int height = _bmp.Size.Height;
for (int heightIdx = 0; heightIdx < height; heightIdx++)
{
for (int widthIdx = 0; widthIdx < width; widthIdx++)
{
Color objImgColor;
objImgColor = _bmp.GetPixel(widthIdx, heightIdx);
int grayScaleBase = (int)((objImgColor.R + objImgColor.G + objImgColor.B) / 3);
Color grayScaleColor;
grayScaleColor = Color.FromArgb(grayScaleBase, grayScaleBase, grayScaleBase);
_bmp.SetPixel(widthIdx, heightIdx, grayScaleColor);
}
}
}
When woring with a large image, the method above is extremely slow. Just try it If you don't believe me. And here is how we implement Lockbits method to do a Grayscale operation on image.
///
/// Grayscale method by using pointer access
///
public void SpeedGrayscale()
{
// Specify width, height, anf pixel format
int imgWidth = _bmp.Width;
int imgHeight = _bmp.Height;
PixelFormat imgPixFormat = _bmp.PixelFormat;
// Create BitmapData and Rectangle object, which will be used
// in Lockbits method
BitmapData bmpData = null;
Rectangle rct = new Rectangle(0, 0, imgWidth, imgHeight);
try
{
// We use unsafe keyword, because this is a pointer operation
unsafe
{
//Lockbits = lock bitmap data to memory
bmpData = _bmp.LockBits(rct, ImageLockMode.ReadWrite, imgPixFormat);
byte* row; // Pointer for a bitmap row
byte* rowElement; // Pointer for a pixel
int intGrayscaleValue; // grayscale value for one pixel
// Loop based on image height (y)
for (int y = 0; y < bmpData.Height; y++)
{
// Find starting memory pointer address for each row
row = (byte*)bmpData.Scan0 + (y * bmpData.Stride);
// Loop through the row (x)
for (int x = 0; x < bmpData.Width; x++)
{
rowElement = row + (x * 3); // find the pixel pointer address
intGrayscaleValue = (rowElement[0] + rowElement[1] + rowElement[2]) / 3;
// assign grayscale value for each pixel element
rowElement[0] = (byte)intGrayscaleValue;
rowElement[1] = (byte)intGrayscaleValue;
rowElement[2] = (byte)intGrayscaleValue;
}
}
// Unlock the bitmap from memory
_bmp.UnlockBits(bmpData);
}
}
catch (Exception ex)
{
throw ex;
}
}
2 comments:
jeg perlu banyak energi rage maca posting awak... isi chat aja lah...
ape aden orange bapak ne...
mlali mai jep...
Post a Comment