C# 查找位图之间差异的最小可能矩形

C# 查找位图之间差异的最小可能矩形,c#,.net,image,bitmap,C#,.net,Image,Bitmap,我正在尝试在我正在编写的VNC类型的应用程序上优化性能,但我在真正优化它时遇到了一些困难 给定两个位图,我想返回第三个位图,大小尽可能小,它完全包含位图之间的差异 我可以返回与位图a/位图B大小相同的位图,其中的差异有颜色,其余部分是透明的,但这不会节省任何实际数据空间,也不会实际优化任何内容(除非位图对完全透明的像素做了一些特殊的处理,但我觉得它们并没有) 不管怎么说,这就是我现在看到的,我可以跟踪第一个更改所在的指针,然后跟踪最后一个更改所在的指针,但是如何将这些指针转换成矩形呢?我怎样才能

我正在尝试在我正在编写的VNC类型的应用程序上优化性能,但我在真正优化它时遇到了一些困难

给定两个位图,我想返回第三个位图,大小尽可能小,它完全包含位图之间的差异

我可以返回与位图a/位图B大小相同的位图,其中的差异有颜色,其余部分是透明的,但这不会节省任何实际数据空间,也不会实际优化任何内容(除非位图对完全透明的像素做了一些特殊的处理,但我觉得它们并没有)

不管怎么说,这就是我现在看到的,我可以跟踪第一个更改所在的指针,然后跟踪最后一个更改所在的指针,但是如何将这些指针转换成矩形呢?我怎样才能将我的全尺寸差异位图裁剪到那个矩形中呢

以下是我目前使用的代码:

var a = previous.Screen;
var b = next.Screen;
Bitmap output = new Bitmap(
Math.Max(a.Width, b.Width),
Math.Max(a.Height, b.Height),
PixelFormat.Format32bppArgb);

Rectangle recta = new Rectangle(Point.Empty, a.Size);
Rectangle rectb = new Rectangle(Point.Empty, b.Size);
Rectangle rectOutput = new Rectangle(Point.Empty, output.Size);

BitmapData aData = a.LockBits(recta, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BitmapData bData = b.LockBits(rectb, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BitmapData outputData = output.LockBits(rectOutput, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

try
{
    unsafe
    {
      byte* aPtr = (byte*) aData.Scan0;
      byte* bPtr = (byte*) bData.Scan0;
      byte* outputPtr = (byte*) outputData.Scan0;

      int h = Math.Min(a.Height, b.Height);
      int w = Math.Min(a.Width, b.Width);

      for (int y = 0; y < h; y++)
      {
        aPtr = (byte*) aData.Scan0;
        bPtr = (byte*) bData.Scan0;
        outputPtr = (byte*) outputData.Scan0;

        aPtr += y*aData.Stride;
        bPtr += y*bData.Stride;
        outputPtr += y*outputData.Stride;

         for (int x = 0; x < w; x++)
         {
           bool bl = false;
           //the three color channels
           for (int j = 0; j < 3; j++)
           {
             if (*aPtr != *bPtr)
             {
               bl = true;
             }

             *outputPtr = (byte) *bPtr;

             outputPtr++;
             aPtr++;
             bPtr++;
          }

          //alpha, when one or mre color channels are different
          if (bl)
           *outputPtr = (byte) ((*aPtr + *bPtr)/2);

          outputPtr++;
          aPtr++;
          bPtr++;
         }
      }
   }

 }
 catch
 {
    if (output != null)
    {
      output.UnlockBits(outputData);
      output.Dispose();
      output = null;
    }
 }
 finally
 {
     a.UnlockBits(aData);
     b.UnlockBits(bData);

     if (output != null)
       output.UnlockBits(outputData);
 }
var a=previous.Screen;
var b=next.Screen;
位图输出=新位图(
数学最大值(a.宽度,b.宽度),
数学最大值(a.高度,b.高度),
PixelFormat.Format32bppArgb);
矩形recta=新矩形(Point.Empty,a.Size);
矩形rectb=新矩形(Point.Empty,b.Size);
矩形rectOutput=新矩形(Point.Empty,output.Size);
BitmapData aData=a.LockBits(recta,ImageLockMode.ReadOnly,PixelFormat.Format32bppArgb);
BitmapData bData=b.LockBits(rectb,ImageLockMode.ReadOnly,PixelFormat.Format32bppArgb);
BitmapData outputData=output.LockBits(rectOutput,ImageLockMode.ReadWrite,PixelFormat.Format32bppArgb);
尝试
{
不安全的
{
字节*aPtr=(字节*)aData.Scan0;
字节*bPtr=(字节*)bData.Scan0;
字节*outputPtr=(字节*)outputData.Scan0;
int h=数学最小值(a.高度,b.高度);
int w=数学最小值(a.宽度,b.宽度);
对于(int y=0;y
是否允许压缩?您可以用不同于位图的格式发送它。此外,我认为透明度只是增加了数据。您至少可以将其设置为24位图像,以便每像素保存一个字节?其他选项是创建8位调色板,或者使用16位颜色,可能是PNG格式。。我不确定你的要求是什么..压缩是可以允许的,结果需要在另一端放入一个PictureBox。这就是全部。24位图像不会失去透明度吗?是的,当然会,但只有当你稍后试图将该图像覆盖到其他图像上时,这才真正重要。顺便问一下,发生了什么样的变化?它们是基于向量的更改,如“划一条线”,还是任意更改?如果你能将更改表示为指令,这可能是最有效的方法。嗯,这是一个桌面共享应用程序。因此,可能是在最后一张图像拍摄期间(移动窗口或突出显示文本等),桌面上发生的变化,但很可能这两张图像的许多部分在任何给定时间都会保持不变,因此我相信像这样的差异算法,如果我能找出更好的点,将有助于加快传输速度。我认为将这些差异作为图像发送没有多大用处,tbh。如果您想要简单快速,可以选择RLE压缩字节数组之类的东西。