Bitmap调用LockBits[C#]

//#define ADDRESS_MODE

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BitmapDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void LockUnlockBitsExample(PaintEventArgs e)
        {

            // Create a new bitmap.
            Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg");
            
            // Lock the bitmap's bits.  
            int x = 30;
            int y = 40;
            Rectangle rect = new Rectangle(x, y, bmp.Width-2*x, bmp.Height-2*y);
            System.Drawing.Imaging.BitmapData bmpData =
                bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
                bmp.PixelFormat);

            // Get the address of the first line.

#if ADDRESS_MODE

            unsafe
            {
                byte* ptr = (byte*)bmpData.Scan0;

                int row = 0;
                int col = 0;

                //ptr[row * bmpData.Stride + col * 3 + 2] = 0xff;

                for (row = 0; row < rect.Height; ++row)
                {
                    for (col = 0; col < rect.Width; ++col)
                    {
                        ptr[row * bmpData.Stride  + col * 3 + 2] = 0xff;
                    }
                }
                
                //for (int c = 0; c < rect.Width; ++c )
                //{
                //    ptr[(row + 1) * bmpData.Stride + c * 3 + 2] = 0xff;
                //}
            }

#else
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            int bytes = Math.Abs(bmpData.Stride) * bmpData.Height;
            byte[] rgbValues = new byte[bytes];

            // Copy the RGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

            // Set every third value to 255. A 24bpp bitmap will look red.  
            for (int counter = 2; counter < rgbValues.Length; counter += 3)
                rgbValues[counter] = 255;

            // Copy the RGB values back to the bitmap
            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
#endif

            // Unlock the bits.
            bmp.UnlockBits(bmpData);
            
            // Draw the modified image.
            //e.Graphics.DrawImage(bmp, 0, 150);
            e.Graphics.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height);
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            LockUnlockBitsExample(e);
        }
    }
}

总结

Bitmap对象是对GDI+的.NET封装。

(byte*)bmpData.Scan0为锁定区域首字节的地址,bmpData.Stride为扫描宽度。

锁定区域的内存是一块连续存储空间,其大小为Math.Abs(bmpData.Stride) * bmpData.Height。

unsafe private void buttonTest_Click(object sender, EventArgs e)
        {
            Bitmap bitmap = new Bitmap("demo.bmp");
            this.pictureBoxLeft.Image = bitmap;

            IntPtr p = Marshal.AllocHGlobal(300 * 500 * 4);
            UInt32* pUInt32 = (UInt32*)p;

            for (int i = 0; i < 300 * 500; ++i)
                *(pUInt32 + i) = 0xffff0000;

            BitmapData bitmapData = new BitmapData();
            bitmapData.Width = 500;
            bitmapData.Height = 300;
            bitmapData.Stride = 4 * bitmapData.Width;
            bitmapData.PixelFormat = PixelFormat.Format32bppArgb;
            bitmapData.Scan0 = p;

            // Lock a 50x30 rectangular portion of the bitmap for writing.
            Rectangle rect = new Rectangle(20, 10, 500, 300);

            BitmapData bmpData = bitmap.LockBits(
               rect,
               ImageLockMode.WriteOnly | ImageLockMode.UserInputBuffer,
               PixelFormat.Format32bppArgb,
               bitmapData);

            // Commit the changes and unlock the 50x30 portion of the bitmap.  
            bitmap.UnlockBits(bmpData);

            this.pictureBoxRight.Image = bitmap;

            Marshal.FreeHGlobal(p);
            p = IntPtr.Zero;
        }


------------------------------------------------------------------------------------

https://msdn.microsoft.com/en-us/library/windows/desktop/ms536298(v=vs.85).aspx

The Bitmap::LockBits method locks a rectangular portion of this bitmap and provides a temporary buffer that you can use to read or write pixel data in a specified format. Any pixel data that you write to the buffer is copied to theBitmap object when you call Bitmap::UnlockBits.

------------------------------------------------------------------------------------


资料

http://timothyqiu.com/archives/lockbits-in-gdiplus/

http://msdn.microsoft.com/en-us/library/windows/desktop/ms536298(v=vs.85).aspx

使用lockbits方法处理图像

http://blog.sina.com.cn/s/blog_4e3e2ce4010009on.html

GDI/GDI+(1): 将Bitmap导出为Byte[]

http://blog.csdn.net/oldmtn/article/details/22277089

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值