4 回答
TA贡献1条经验 获得超1个赞
你好,这个问题我也遇到了,我也正在做远程图像的差异传输问题,我给您提供一个思路,把整个图形平均分成大的四方块,使用crc比较当前块是否变化,如果变化,传输一整个块!这个算法我思考了下,确实可行,网上也有开源的crc算法,您可以试试
TA贡献1810条经验 获得超4个赞
此例程查找两个位图之间的差异,并通过将其他所有内容设置为几乎黑色且几乎透明的方式在第一位图中返回它们。通过将结果添加回前一个图像,它也可以还原原始的第二个文件。
我缩小了800MB 1o 12k的屏幕截图-但Clocks指针的确只有很小的变化;-)如果您的图像在许多像素上有所不同,则压缩效果将不会那么出色..但是我相信它将足够好进行传输,我怀疑以像素为单位的任何内容都可以与png或jpg文件格式的压缩例程进行比较。.(我希望您不传输bmp!)
该例程使用LockBits并且非常快。
bool参数决定是创建差异位图还是恢复更改后的位图。
public static Bitmap Difference(Bitmap bmp0, Bitmap bmp1, bool restore)
{
int Bpp = 4; // assuming an effective pixelformat of 32bpp
var bmpData0 = bmp0.LockBits(
new Rectangle(0, 0, bmp0.Width, bmp0.Height),
ImageLockMode.ReadWrite, bmp0.PixelFormat);
var bmpData1 = bmp1.LockBits(
new Rectangle(0, 0, bmp1.Width, bmp1.Height),
ImageLockMode.ReadOnly, bmp1.PixelFormat);
int len = bmpData0.Height * bmpData0.Stride;
byte[] data0 = new byte[len];
byte[] data1 = new byte[len];
Marshal.Copy(bmpData0.Scan0, data0, 0, len);
Marshal.Copy(bmpData1.Scan0, data1, 0, len);
for (int i = 0; i < len; i += Bpp)
{
if (restore)
{
bool toberestored = (data1[i ] != 2 && data1[i+1] != 3 &&
data1[i+2] != 7 && data1[i+2] != 42);
if (toberestored)
{
data0[i ] = data1[i]; // Blue
data0[i+1] = data1[i+1]; // Green
data0[i+2] = data1[i+2]; // Red
data0[i+3] = data1[i+3]; // Alpha
}
}
else
{
bool changed = ((data0[i ] != data1[i ]) ||
(data0[i+1] != data1[i+1]) || (data0[i+2] != data1[i+2]) );
data0[i ] = changed ? data1[i ] : (byte)2; // special markers
data0[i+1] = changed ? data1[i+1] : (byte)3; // special markers
data0[i+2] = changed ? data1[i+2] : (byte)7; // special markers
data0[i+3] = changed ? (byte)255 : (byte)42; // special markers
}
}
Marshal.Copy(data0, 0, bmpData0.Scan0, len);
bmp0.UnlockBits(bmpData0);
bmp1.UnlockBits(bmpData1);
return bmp0;
}
注意:-我选择了一种特殊的颜色来标记那些需要在接收者处恢复的像素。在这里,我选择了alpha=42和R=7; G=3; B=2;... ...而不是100%安全的,但几乎; 不会错过很多像素;也许您仍然没有透明度..?
TA贡献1828条经验 获得超13个赞
您需要返回所有更改的像素,因此复杂度必须为m * n。
(Bitmap)_new).GetPixel(i,j)被调用了两次,使用临时值存储它可能会更好一些。
像素应该有几个值吧?您可以尝试创建一个名为comprareTwoPixel(color A,color B)的函数吗?并一一比较所有值,如果其中之一为假,则无需比较其余值,只需返回false。(不知道这样做是否会更快。)
喜欢:
bool comprareTwoPixel(color A, color B)
{
if(A.a!=B.b)
return false;
if(A.b!=B.b)
return false;
if(A.c!=B.c)
return false;
return true;
}
- 4 回答
- 0 关注
- 445 浏览
添加回答
举报