기본 콘텐츠로 건너뛰기

C# - LockBit

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];
                // calculate new pixel value
                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];
             
            // calculate new pixel value
            pixels[currentLine + x] = (byte)oldBlue;
            pixels[currentLine + x + 1] = (byte)oldGreen;
            pixels[currentLine + x + 2] = (byte)oldRed;
        }
    }
    // copy modified bytes back
    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);
             
            // calculate new pixel value
            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"); }

댓글

이 블로그의 인기 게시물

C# - Serial Port ASCII/HEX Format

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO.Ports; namespace SerialTest1 {     public partial class Form1 : Form     {         delegate void MyDelegate();      //델리게이트 선언(크로스 쓰레드 해결하기 위한 용도)         bool SendForamt = true;          // true : ASCII   false : HEX         bool ReceiveFormat = true;       // true : ASCII   false : HEX         public Form1()         {             InitializeComponent();          ...

C# - Windows Form 에 있는 control 찾기

// 아래 코드는 form 의 최상위 control만 찾을 수 있음. // panle, groubbox ... 내부에 있는 control은 찾지 못함. Control GetControlByName(string Name) {     foreach (Control c in this.Controls)         if (c.Name == Name)             return c;     return null; } // form 의 모든 control을 찾을 수 있음. string name = "btnBit" + (i + 1).ToString("D2"); var tmpBtn = this.Controls.Find(name, true).FirstOrDefault(); if (tmpBtn != null) {     if (value == 1) tmpBtn.BackColor = Color.Lime;     else tmpBtn.BackColor = Color.Gray; }

C# - ARGB 색상

속성 A 이  Color  구조체의 알파 구성 요소 값을 가져옵니다. Alice Blue ARGB 값이  #FFF0F8FF 인 시스템 정의 색을 가져옵니다. Antique White ARGB 값이  #FFFAEBD7 인 시스템 정의 색을 가져옵니다. Aqua ARGB 값이  #FF00FFFF 인 시스템 정의 색을 가져옵니다. Aquamarine ARGB 값이  #FF7FFFD4 인 시스템 정의 색을 가져옵니다. Azure ARGB 값이  #FFF0FFFF 인 시스템 정의 색을 가져옵니다. B 이  Color  구조체의 파랑 구성 요소 값을 가져옵니다. Beige ARGB 값이  #FFF5F5DC 인 시스템 정의 색을 가져옵니다. Bisque ARGB 값이  #FFFFE4C4 인 시스템 정의 색을 가져옵니다. Black ARGB 값이  #FF000000 인 시스템 정의 색을 가져옵니다. Blanched Almond ARGB 값이  #FFFFEBCD 인 시스템 정의 색을 가져옵니다. Blue ARGB 값이  #FF0000FF 인 시스템 정의 색을 가져옵니다. Blue Violet ARGB 값이  #FF8A2BE2 인 시스템 정의 색을 가져옵니다. Brown ARGB 값이  #FFA52A2A 인 시스템 정의 색을 가져옵니다. Burly Wood ARGB 값이  #FFDEB887 인 시스템 정의 색을 가져옵니다. Cadet Blue ARGB 값이  #FF5F9EA0 인 시스템 정의 색을 가져옵니다. Chartreuse ARGB 값이  #FF7FFF00 인 시스템 정의 색을 가져옵니다. Chocolate ARGB 값이  #FFD2691E 인 시스템 정의 색을 가져옵니다. Coral ARGB ...