结果:
private void Memory_Click(object sender, EventArgs e) { if (curBitmap != null) { myTimer.ClearTimer(); myTimer.Start(); Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);//新建矩形绘板 System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat); IntPtr ptr = bmpData.Scan0; int bytes = curBitmap.Width * curBitmap.Height * 3; byte[] rgbValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); //将intPtr变量ptr(非托管对象)复制到一维的字节数组rgbValues(托管对象)中 double colorTemp = 0; for (int i = 0; i < rgbValues.Length; i += 3) { colorTemp = rgbValues[i + 2] * 0.299 + rgbValues[i + 1] * 0.587 + rgbValues[i] * 0.114; rgbValues[i] = rgbValues[i + 1] = rgbValues[i + 2] = (byte)colorTemp; } System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);//将一维的字节数组rgbValues(托管对象)复制到intPtr变量ptr(非托管对象)中 curBitmap.UnlockBits(bmpData); myTimer.Stop(); textBox1.Text = myTimer.Duration.ToString("####.##") + "毫秒"; Invalidate(); } }
如果是任意大小的24位彩色图像,则上述程序就不再适用, 需要修改,修改后的代码如下: private void memory_Click(object sender^ EventArgs e) ( if (curBitmap != null) { //位图矩形 Rectangle rect = new Rectangle (0, 0, curBitmap^Width, curBitmap.Height); //以可读写的方式锁定全部位图像素 System.Drawing»Imaging *BitmapData bmpData - curBitmap* LockBits(rect, System.Drawing ,Imaging.ImageLockMode- ReadWriteF curBitmap,PixelFormat}; 〃很到首地址 IntPtr ptr = bmpData^ScanO; //定义被锁定的数组大小,由位图数据与未用空间组成 int bytes 宜 bmpData.Stride ♦ bmpData.Height; byte[] rgbValues = new byte[bytes]; //复制被锁定的位图像素值到该教组内 Systern.Runtime.InteropServices.Marshal.Copy(ptrf rgbValues, 0z bytes); 〃灰度化 double colorTemp = 0; for (int i = 0; i < bmpData.Height; i++) { //只处理每行中是图像像素的数据,舍弃未用空间 for (int j » 0; j < bmpData.Width * 3; j += 3) { colorTemp = rgbValues(i * bmpData.Stride + j + 2] * 0.299 + rgbValues[i * bmpData.Stride + j + 1] • 0.587 + rgbValues[i * bmpData-Stride + j] * 0.114; rgbValues[i * bmpData*Stride + j] = rgbValues[i * brnpData.Stride + j + 1] rgbValues fi * bmpData.Stride + j + 2] « (byte)colorTemp; //把数组复制回位图 System.Runtime.InteropServices.Marshal•Copy(rgbValues# 0r ptrz bytes); //解锁位图像素 curBitmapeUnlockBit3(bmpData); 〃对窗体进行重新籍制,这将强制执行Paint事件处理程序 InvalidateO/