先介绍下我的目的:
1.我打算通过LockBits和Marshal.Copy来读取2图像的每一点的RGB值。
2.然后对部分点的RGB进行操作(例如半透明吧)
3.在回写到图像上,获得新的图片。
我自己试验了下,发现有问题存在---那就是形成新的图像上的2号图像是斜的,why?
大家先看下我代码,是不是代码有问题?
或者是不是读取的RGB有问题。(我试验过对于同一张图像,(用2次)新的图像没有问题。)
部分代码是这样的:
1:读取RGB: int height = source.Height;
int width = source.Width;
//
Rectangle rect = new Rectangle(0, 0, width, height);
System.Drawing.Imaging.BitmapData bitmapd = source.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
IntPtr ip = bitmapd.Scan0;
byte[] pixelValues = new byte[height * width*3];//这里RGB三个,则×3
System.Runtime.InteropServices.Marshal.Copy(ip, pixelValues, 0, height * width*3 ); source.UnlockBits(bitmapd); //RGB中的方向相反。
R = new int[height, width];
G = new int[height, width];
B = new int[height, width]; int ipoint = 0;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
R[i, j] = Convert.ToInt32(pixelValues[ipoint++]);
G[i, j] = Convert.ToInt32(pixelValues[ipoint++]);
B[i, j] = Convert.ToInt32(pixelValues[ipoint++]);
}
}
2:回写RGB int height = aim.Height;
int width = aim.Width;
int ipoint = 0;
byte[] pixelValue2 = new byte[height * width * 3]; for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
pixelValue2[ipoint++] = Convert.ToByte(R[i, j]);
pixelValue2[ipoint++] = Convert.ToByte(G[i, j]);
pixelValue2[ipoint++] = Convert.ToByte(B[i, j]);
}
} Rectangle rect2 = new Rectangle(0, 0, width, height);
System.Drawing.Imaging.BitmapData bitmapd2 = aim.LockBits(rect2, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
IntPtr ip2 = bitmapd2.Scan0;
//byte[] pixelValues = new byte[height * width * 3];//这里RGB三个,则×3
System.Runtime.InteropServices.Marshal.Copy(pixelValue2, 0, ip2, height * width * 3); aim.UnlockBits(bitmapd2);
1.我打算通过LockBits和Marshal.Copy来读取2图像的每一点的RGB值。
2.然后对部分点的RGB进行操作(例如半透明吧)
3.在回写到图像上,获得新的图片。
我自己试验了下,发现有问题存在---那就是形成新的图像上的2号图像是斜的,why?
大家先看下我代码,是不是代码有问题?
或者是不是读取的RGB有问题。(我试验过对于同一张图像,(用2次)新的图像没有问题。)
部分代码是这样的:
1:读取RGB: int height = source.Height;
int width = source.Width;
//
Rectangle rect = new Rectangle(0, 0, width, height);
System.Drawing.Imaging.BitmapData bitmapd = source.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
IntPtr ip = bitmapd.Scan0;
byte[] pixelValues = new byte[height * width*3];//这里RGB三个,则×3
System.Runtime.InteropServices.Marshal.Copy(ip, pixelValues, 0, height * width*3 ); source.UnlockBits(bitmapd); //RGB中的方向相反。
R = new int[height, width];
G = new int[height, width];
B = new int[height, width]; int ipoint = 0;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
R[i, j] = Convert.ToInt32(pixelValues[ipoint++]);
G[i, j] = Convert.ToInt32(pixelValues[ipoint++]);
B[i, j] = Convert.ToInt32(pixelValues[ipoint++]);
}
}
2:回写RGB int height = aim.Height;
int width = aim.Width;
int ipoint = 0;
byte[] pixelValue2 = new byte[height * width * 3]; for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
pixelValue2[ipoint++] = Convert.ToByte(R[i, j]);
pixelValue2[ipoint++] = Convert.ToByte(G[i, j]);
pixelValue2[ipoint++] = Convert.ToByte(B[i, j]);
}
} Rectangle rect2 = new Rectangle(0, 0, width, height);
System.Drawing.Imaging.BitmapData bitmapd2 = aim.LockBits(rect2, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
IntPtr ip2 = bitmapd2.Scan0;
//byte[] pixelValues = new byte[height * width * 3];//这里RGB三个,则×3
System.Runtime.InteropServices.Marshal.Copy(pixelValue2, 0, ip2, height * width * 3); aim.UnlockBits(bitmapd2);
给我点方向,告诉我哪里出来的问题也好啊。
我现在怀疑莫非是不是这个方法读取的RGB数据排列有问题?
我采用getpixel()方法的时候,得到 的RGB值,他们之间好像不同。
那么,究竟是哪里的问题?详细讲解一下关于LockBits和Marshal.Copy的关系也好啊。。谢谢了先~
期待中。
首先这里byte[] pixelValues = new byte[height * width*3];//要用height * BitmapData.Stride..这里。pixelValue2[ipoint++] 这样能对吗? 一次移动一个字节,不是丢字节了。
我明白如下:
其实在bitmapdata下它宽度其实是stride即大于或者等于图像width的一个数(4的倍数)。
我错误的根源呢就是: 在2副大小不同的图像上我错误的进行了多余位数的计算,从而产生了错误。
(是不是这样??)怎么给分啊。楼上给你分。。
*号代表 数据 #代表冗余假如7*3的
看得明白吗 8就是stride 如果stride刚好等于宽 程序可能是没问题的
*******#*******#*******#程序具体我没测 你自己看看吧try
{
int iWidth = Source.Width;
int iHeight = Source.Height; Rectangle rect = new Rectangle(0, 0, Source.Width, Source.Height);
BitmapData bd = Source.LockBits(rect, ImageLockMode.ReadWrite, Source.PixelFormat);
IntPtr iPtr = bd.Scan0;
int iBytes = bd.Stride * bd.Height * 4;
byte[] PixelValues = new byte[iBytes];
System.Runtime.InteropServices.Marshal.Copy(iPtr, PixelValues, 0, iBytes);
int t = bd.Stride - bd.Width;
Source.UnlockBits(bd); // 注意这个地方图像的两维方向与数组两维的方向是转置的关系
R = new int[iHeight, iWidth];
G = new int[iHeight, iWidth];
B = new int[iHeight, iWidth];
int iPoint = 0;
for (int i = 0; i < iHeight; i++)
{
for (int j = 0; j < iWidth; j++)
{
// 注意,Windows 中三基色的排列顺序是 BGR 而不是 RGB!
B[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
G[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
R[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
iPoint++;
}
iPoint = iPoint + t;
}
return true;
}
{
int iWidth = Source.Width;
int iHeight = Source.Height; Rectangle rect = new Rectangle(0, 0, Source.Width, Source.Height);
BitmapData bd = Source.LockBits(rect, ImageLockMode.ReadWrite, Source.PixelFormat);
IntPtr iPtr = bd.Scan0;
int iBytes = bd.Stride * bd.Height * 3;
byte[] PixelValues = new byte[iBytes];
System.Runtime.InteropServices.Marshal.Copy(iPtr, PixelValues, 0, iBytes);
int t = bd.Stride - bd.Width;
Source.UnlockBits(bd); // 注意这个地方图像的两维方向与数组两维的方向是转置的关系
R = new int[iHeight, iWidth];
G = new int[iHeight, iWidth];
B = new int[iHeight, iWidth];
int iPoint = 0;
for (int i = 0; i < iHeight; i++)
{
for (int j = 0; j < iWidth; j++)
{
// 注意,Windows 中三基色的排列顺序是 BGR 而不是 RGB!
B[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
G[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
R[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
}
iPoint = iPoint + t;
}
return true;
}