reference
//// LockBits and Unsafe and parallel
private
void
ProcessUsingLockbitsAndUnsafeAndParallel(Bitmap processedBitmap)
{
unsafe
{
BitmapData bitmapData = processedBitmap.LockBits(
new
Rectangle(0, 0, processedBitmap.Width, processedBitmap.Height), ImageLockMode.ReadWrite, processedBitmap.PixelFormat);
int
bytesPerPixel = System.Drawing.Bitmap.GetPixelFormatSize(processedBitmap.PixelFormat) / 8;
int
heightInPixels = bitmapData.Height;
int
widthInBytes = bitmapData.Width * bytesPerPixel;
byte
* PtrFirstPixel = (
byte
*)bitmapData.Scan0;
Parallel.For(0, heightInPixels, y =>
{
byte
* currentLine = PtrFirstPixel + (y * bitmapData.Stride);
for
(
int
x = 0; x < widthInBytes; x = x + bytesPerPixel)
{
int
oldBlue = currentLine[x];
int
oldGreen = currentLine[x + 1];
int
oldRed = currentLine[x + 2];
currentLine[x] = (
byte
)oldBlue;
currentLine[x + 1] = (
byte
)oldGreen;
currentLine[x + 2] = (
byte
)oldRed;
}
});
processedBitmap.UnlockBits(bitmapData);
}
}
//// LockBits and Unsafe
private
void
ProcessUsingLockbitsAndUnsafe(Bitmap processedBitmap)
{
unsafe
{
BitmapData bitmapData = processedBitmap.LockBits(
new
Rectangle(0, 0, processedBitmap.Width, processedBitmap.Height), ImageLockMode.ReadWrite, processedBitmap.PixelFormat);
int
bytesPerPixel = System.Drawing.Bitmap.GetPixelFormatSize(processedBitmap.PixelFormat) / 8;
int
heightInPixels = bitmapData.Height;
int
widthInBytes = bitmapData.Width * bytesPerPixel;
byte
* ptrFirstPixel = (
byte
*)bitmapData.Scan0;
for
(
int
y = 0; y < heightInPixels; y++)
{
byte
* currentLine = ptrFirstPixel + (y * bitmapData.Stride);
for
(
int
x = 0; x < widthInBytes; x = x + bytesPerPixel)
{
int
oldBlue = currentLine[x];
int
oldGreen = currentLine[x + 1];
int
oldRed = currentLine[x + 2];
currentLine[x] = (
byte
)oldBlue;
currentLine[x + 1] = (
byte
)oldGreen;
currentLine[x + 2] = (
byte
)oldRed;
}
}
processedBitmap.UnlockBits(bitmapData);
}
}
//// LockBits and Marshal Copy
private
void
ProcessUsingLockbits(Bitmap processedBitmap)
{
BitmapData bitmapData = processedBitmap.LockBits(
new
Rectangle(0, 0, processedBitmap.Width, processedBitmap.Height), ImageLockMode.ReadWrite, processedBitmap.PixelFormat);
int
bytesPerPixel = Bitmap.GetPixelFormatSize(processedBitmap.PixelFormat) / 8;
int
byteCount = bitmapData.Stride * processedBitmap.Height;
byte
[] pixels =
new
byte
[byteCount];
IntPtr ptrFirstPixel = bitmapData.Scan0;
Marshal.Copy(ptrFirstPixel, pixels, 0, pixels.Length);
int
heightInPixels = bitmapData.Height;
int
widthInBytes = bitmapData.Width * bytesPerPixel;
for
(
int
y = 0; y < heightInPixels; y++)
{
int
currentLine = y * bitmapData.Stride;
for
(
int
x = 0; x < widthInBytes; x = x + bytesPerPixel)
{
int
oldBlue = pixels[currentLine + x];
int
oldGreen = pixels[currentLine + x + 1];
int
oldRed = pixels[currentLine + x + 2];
pixels[currentLine + x] = (
byte
)oldBlue;
pixels[currentLine + x + 1] = (
byte
)oldGreen;
pixels[currentLine + x + 2] = (
byte
)oldRed;
}
}
Marshal.Copy(pixels, 0, ptrFirstPixel, pixels.Length);
processedBitmap.UnlockBits(bitmapData);
}
//// getPixel/setPixel
private
void
ProcessUsingGetPixelSetPixel(Bitmap processedBitmap)
{
int
width = processedBitmap.Width;
int
height = processedBitmap.Height;
for
(
int
x = 0; x < width; x++)
{
for
(
int
y = 0; y < height; y++)
{
Color oldPixel = processedBitmap.GetPixel(x, y);
Color newPixel = oldPixel;
processedBitmap.SetPixel(x, y, newPixel);
}
}
}
////
////
[ LockBits() ]
private void btnChangColor_Click(object sender, EventArgs e)
{
Stopwatch sw = new Stopwatch();
sw.Start();
Rectangle rect = new Rectangle(0, 0, img.Width, img.Height);
System.Drawing.Imaging.BitmapData bmpData =
img.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
img.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int bytes = Math.Abs(bmpData.Stride) * img.Height;
byte[] rgbValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
int numBytes = 0;
for (int y = 0; y < img.Height; y++)
{
for (int x = 0; x < img.Width; x++)
{
numBytes = (y * (img.Width * 4)) + (x * 4);
if (rgbValues[numBytes] != 255
&& rgbValues[numBytes + 1] != 255
&& rgbValues[numBytes + 2] != 255)
{
rgbValues[numBytes] = 0;
rgbValues[numBytes + 1] = 0;
rgbValues[numBytes + 2] = 255;
}
}
}
// Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
// Unlock the bits.
img.UnlockBits(bmpData);
pictureBox1.Invalidate();
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString() + "ms");
}
[SetPixel() / GetPixel()]
private void btnChangColor02_Click(object sender, EventArgs e)
{
Stopwatch sw = new Stopwatch();
sw.Start();
Color co;
for (int y = 0; y < img.Height; y++)
{
for (int x = 0; x < img.Width; x++)
{
co = img.GetPixel(x, y);
if (co.R != 255 && co.G != 255 && co.B != 255)
{
co = Color.FromArgb(255, 0, 0);
img.SetPixel(x, y, co); // 해당 좌표 픽셀의 컬러값을 변경
}
}
}
pictureBox1.Invalidate();
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString() + "ms");
}
댓글