我有一些可能对你有用的东西。这个想法是只保存图像之间的差异,然后根据起始图像和保存的更改重新创建所有图像。
为此,您只需要对图像字节进行异或运算。此方法允许您获得两个图像之间的差异(array 参数):
protected void ApplyXor(Bitmap img1, Bitmap img2, byte[] array)
{
const ImageLockMode rw = ImageLockMode.ReadWrite;
const PixelFormat argb = PixelFormat.Format32bppArgb;
var locked1 = img1.LockBits(new Rectangle(0, 0, img1.Width, img1.Height), rw, argb);
var locked2 = img2.LockBits(new Rectangle(0, 0, img2.Width, img2.Height), rw, argb);
try
{
ApplyXor(locked2, locked1, array);
}
finally
{
img1.UnlockBits(locked1);
img2.UnlockBits(locked2);
}
}
有了前面的img1位图和返回的array,你可以用这个方法得到img2:
protected void ApplyXor(Bitmap img1, byte[] array, Bitmap img2)
{
const ImageLockMode rw = ImageLockMode.ReadWrite;
const PixelFormat argb = PixelFormat.Format32bppArgb;
var locked1 = img1.LockBits(new Rectangle(0, 0, img1.Width, img1.Height), rw, argb);
var locked2 = img2.LockBits(new Rectangle(0, 0, img2.Width, img2.Height), rw, argb);
try
{
ApplyXor(locked1, array, locked2);
}
finally
{
img1.UnlockBits(locked1);
img2.UnlockBits(locked2);
}
}
这里是其他所需的方法:
private unsafe void ApplyXor(BitmapData img1, BitmapData img2, byte[] array)
{
byte* prev0 = (byte*)img1.Scan0.ToPointer();
byte* cur0 = (byte*)img2.Scan0.ToPointer();
int height = img1.Height;
int width = img1.Width;
int halfwidth = width / 2;
fixed (byte* target = array)
{
ulong* dst = (ulong*)target;
for (int y = 0; y < height; ++y)
{
ulong* prevRow = (ulong*)(prev0 + img1.Stride * y);
ulong* curRow = (ulong*)(cur0 + img2.Stride * y);
for (int x = 0; x < halfwidth; ++x)
{
if (curRow[x] != prevRow[x])
{
int a = 0;
}
*(dst++) = curRow[x] ^ prevRow[x];
}
}
}
}
private unsafe void ApplyXor(BitmapData img1, byte[] array, BitmapData img2)
{
byte* prev0 = (byte*)img1.Scan0.ToPointer();
byte* cur0 = (byte*)img2.Scan0.ToPointer();
int height = img1.Height;
int width = img1.Width;
int halfwidth = width / 2;
fixed (byte* target = array)
{
ulong* dst = (ulong*)target;
for (int y = 0; y < height; ++y)
{
ulong* prevRow = (ulong*)(prev0 + img1.Stride * y);
ulong* curRow = (ulong*)(cur0 + img2.Stride * y);
for (int x = 0; x < halfwidth; ++x)
{
curRow[x] = *(dst++) ^ prevRow[x];
}
}
}
}
注意:您必须将项目配置为允许不安全。
使用以前的方法,您可以执行以下操作:
- 保存 img1 位图
- 获取img2位图,异或得到数组(例如array2)
- 对于 img3,获取与 img2(例如数组 3)的 XOR。现在,不需要 img2
- 对于 img4,获取与 img3 (array4) 的 XOR。现在,不需要 img3
- ...
您有 img1 和 array2、array3、array4...,您可以重新创建所有图像:
- img1 和 array2 异或得到 img2
- img2 和 array3 异或得到 img3
- ...
如果您需要通过 TCP 发送视频,您可以发送图像发送一个图像和 XOR 数组(差异)。或者更好的是,使用 K4os.Compression.LZ4 压缩 XOR 数组。