目前操作位图的主流方法有三种:
1、基于Bitmap像素的处理方法,以GetPixel()和SetPixel()方法为主。方法调用简单,但是效率偏低。
2、基于内存的像素操作方法,以System.Runtime.InteropServices.Marshal.Copy()方法将数据变为非托管资源,操作后再写入内存。
3、基于指针的操作方式,效率最高,但是对使用者的能力有要求,能力不够者容易造成内存溢出。
第二种方法的一个实例:
1 //大图逐行遍历,y为行索引 2 for (var y = 0; y < destHeight; y++) 3 { 4 //小图。把一行数据读入数组。第一个参数是起始位。 5 System.Runtime.InteropServices.Marshal.Copy(srcScan0 + y * srcStride, srcBuffer, 0, srcStride); 6 //大图。 7 System.Runtime.InteropServices.Marshal.Copy(dstScan0 + y * dstStride, dstBuffer, 0, dstStride); 8 9 //大图逐列,rgb三色.(与源码相比做了修改,遍历长度减小,数值因为是灰度值,计算了变为了三分之一。) 10 for (var x = 0; x < destWidth; x ++) 11 { 12 //字节总索引 13 int fullIndex = 3*x; 14 //相乘,再除以255。返回一个byte 15 //dstBuffer[x] = channelProcessFunction(ref srcBuffer[x], ref dstBuffer[x]); 16 var blendValue = channelProcessFunction(ref srcBuffer[fullIndex], ref dstBuffer[fullIndex]); 17 dstBuffer[fullIndex + 2] = blendValue; 18 dstBuffer[fullIndex + 1] = blendValue; 19 dstBuffer[fullIndex] = blendValue; 20 } 21 //写回托管内存 22 System.Runtime.InteropServices.Marshal.Copy(dstBuffer, 0, dstScan0 + y * dstStride, dstStride); 23 }