快速比较2字节数组的方法

时间:2013-11-20 12:04:44

标签: c# image bytearray

我正在尽快将jpeg图像上传到网络服务(这是我的要求)。

我正在使用对Web服务的异步调用,我在计时器中调用它。

我正在尝试尽可能地优化并倾向于使用旧笔记本电脑进行测试。在正常/合理的构建PC上都可以。在笔记本电脑上,我的RAM使用率很高。

我知道使用旧款笔记本电脑可以获得更高的RAM使用率,但我想知道应用程序可以使用的最低规格的PC。

正如您在下面的代码中看到的,我将jpeg图像转换为字节数组,然后上传字节数组。

如果我可以减少/压缩/压缩再见数组,那么我希望这将是改善内存使用的一种方法。

我知道jpegs已经被压缩但是如果我将当前字节数组与前一个byre数组进行比较,那么上传这个字节数组之间的差异我可能会在某些字节值为零的基础上进一步压缩它。

如果我使用视频编码器(可以做到这一点)我就不会像我想的那样实时。

是否有比较2字节数组和输出到第3字节数组的最佳方法?我环顾四周但找不到我喜欢的答案。

这是我在客户端的代码:

bool _uploaded = true;
private void tmrLiveFeed_Tick(object sender, EventArgs e)
{
  try
  {
      if (_uploaded)
      {
        _uploaded = false;
          _live.StreamerAsync(Shared.Alias, imageToByteArray((Bitmap)_frame.Clone()), Guid.NewGuid().ToString()); //web service being called here
      }
  }
  catch (Exception _ex)
  {
      //do some thing but probably time out error here
  }
}

//web service has finished the client invoke 
void _live_StreamerCompleted(object sender, AsyncCompletedEventArgs e)
{
 _uploaded = true; //we are now saying we start to upload the next byte array
}

private wsLive.Live _live = new wsLive.Live(); //web service 
private byte[] imageToByteArray(Image imageIn)
{
  MemoryStream ms = new MemoryStream();
  imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);  //convert image to best image compression
  imageIn.Dispose();
  return ms.ToArray();
}

感谢...

2 个答案:

答案 0 :(得分:1)

如果您的目标是确定两个字节数组是否包含完全相同的数据,您可以创建一个MD5哈希并比较其他人建议的那些。但是在你的问题中,你提到你要上传差异,这意味着比较的结果必须不仅仅是简单的是/否。

由于JPEG已经被压缩,对图像的最小变化可能导致二进制数据的巨大差异。我认为任何两个JPEG都不包含足够容易比较的二进制数据。

对于BMP文件,您可能会发现更改单个像素只会影响一个或几个字节,更重要的是,图像中某个偏移处的像素数据位于两个二进制文件中的相同位置(给定这两个图像具有相同的大小和颜色深度)。因此对于BMP来说,二进制数据的差异直接与图像的差异有关。

简而言之,我认为获取JPEG文件之间的二进制差异不会改善要发送的数据的大小。

答案 1 :(得分:1)

正如C.Evenhuis所说 - JPEG文件被压缩,甚至几个像素的变化导致文件不同。所以 - 比较生成的JPEG文件是没用的。

但是你可以比较你的Image对象 - 找到这个的快速搜索结果:

unsafe Bitmap PixelDiff(Bitmap a, Bitmap b)
{
    Bitmap output = new Bitmap(a.Width, a.Height, PixelFormat.Format32bppArgb);
    Rectangle rect = new Rectangle(Point.Empty, a.Size);
    using (var aData = a.LockBitsDisposable(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb))
    using (var bData = b.LockBitsDisposable(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb))
    using (var outputData = output.LockBitsDisposable(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb))
    {
        byte* aPtr = (byte*)aData.Scan0;
        byte* bPtr = (byte*)bData.Scan0;
        byte* outputPtr = (byte*)outputData.Scan0;
        int len = aData.Stride * aData.Height;
        for (int i = 0; i < len; i++)
        {
            // For alpha use the average of both images (otherwise pixels with the same alpha won't be visible)
            if ((i + 1) % 4 == 0)
                *outputPtr = (byte)((*aPtr  + *bPtr) / 2);
            else
                *outputPtr = (byte)~(*aPtr ^ *bPtr);

            outputPtr++;
            aPtr++;
            bPtr++;
        }
    }
    return output;
}