在C#中可以使用new Bitmap和Bitmap.clone的方法来获取一个Bitmap的备份,这两者实际上是有很大差别的。
代码如下:
Bitmap src = new Bitmap(@"C:\Users\Administrator\Desktop\樱花.png");
Bitmap a = new Bitmap(src);
BitmapData bgraData = a.LockBits(new Rectangle(0, 0, a.Width, a.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
Bitmap r = new Bitmap(a.Width, a.Height);
BitmapData rData = r.LockBits(new Rectangle(0, 0, r.Width, r.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
byte* pSrc = (byte*)bgraData.Scan0;
byte* pR = (byte*)rData.Scan0;
for (int j = 0; j < a.Height; j++)
{
for (int i = 0; i < a.Width; i++)
{
pR[0] = pSrc[0];//第一个像素点的b通道值为0
pR[1] = pSrc[1];
pR[2] = pSrc[2];
pR[3] = pSrc[3];
pR += 4;
pSrc += 4;
}
}
r.UnlockBits(rData);
a.UnlockBits(bgraData);
上述代码使用new Bitmap()的方法创建了src图像的备份对象,读取第一个像素的b通道值为0,alpha通道=0;
在看下面代码:
Bitmap src = new Bitmap(@"C:\Users\Administrator\Desktop\樱花.png");
Bitmap a = (Bitmap)src.Clone();
BitmapData bgraData = a.LockBits(new Rectangle(0, 0, a.Width, a.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
Bitmap r = new Bitmap(a.Width, a.Height);
BitmapData rData = r.LockBits(new Rectangle(0, 0, r.Width, r.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
byte* pSrc = (byte*)bgraData.Scan0;
byte* pR = (byte*)rData.Scan0;
for (int j = 0; j < a.Height; j++)
{
for (int i = 0; i < a.Width; i++)
{
pR[0] = pSrc[0];//第一个像素b通道值为25
pR[1] = pSrc[1];
pR[2] = pSrc[2];
pR[3] = pSrc[3];
pR += 4;
pSrc += 4;
}
}
r.UnlockBits(rData);
a.UnlockBits(bgraData);
上述代码使用src.clone()来创建了src的备份图像对象,但是读取第一个像素的b通道值为25,这里跟第一种方法就出现了偏差。
最后放上原图:
这张原图的第一个像素rgba的值分别为25,25,25,0
我们可以看到上述两种方法只有第二种是对的,因此在读取有透明度通道的PNG对象时,使用clone()方法,最好不要使用new Bitmap方法。
这里给自己的踩坑做个记录。