【问题标题】:Conversion of memory stream to bitmapdata将内存流转换为位图数据
【发布时间】:2013-10-02 19:21:26
【问题描述】:

我发出一个网络请求,以接收一个大的 jpeg 作为字节数组。这又可以转换为内存流。我需要将此数据转换为位图数据,以便我可以再次将其复制到字节数组中。我是否正确假设从内存流返回的字节数组与从位图数据的编组副本返回到字节数组的字节数组不同?

我不想将内存流写入图像,因为由于它的大小以及我使用的是紧凑型 cf C# 2 的事实,它会返回内存不足错误。

这是我对服务器的调用..

HttpWebRequest _request = (HttpWebRequest)WebRequest.Create("A url/00249.jpg");
                _request.Method = "GET";
                _request.Timeout = 5000;
                _request.ReadWriteTimeout = 20000;
                byte[] _buffer;
                int _blockLength = 1024;
                int _bytesRead = 0;
                MemoryStream _ms = new MemoryStream();
                using (Stream _response = ((HttpWebResponse)_request.GetResponse()).GetResponseStream())
                {
                    do
                    {
                        _buffer = new byte[_blockLength];
                        _bytesRead = _response.Read(_buffer, 0, _blockLength);
                        _ms.Write(_buffer, 0, _bytesRead);
                    } while (_bytesRead > 0);
                }

这是我从位图数据中读取字节数组的代码。

 Bitmap Sprite = new Bitmap(_file);
        Bitmapdata RawOriginal = Sprite.LockBits(new Rectangle(0, 0, Sprite.Width, Sprite.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
        int origByteCount = RawOriginal.Stride * RawOriginal.Height;
        SpriteBytes = new Byte[origByteCount];
        System.Runtime.InteropServices.Marshal.Copy(RawOriginal.Scan0, SpriteBytes, 0, origByteCount);
        Sprite.UnlockBits(RawOriginal);

注意: 我不想用这个:

Bitmap Sprite = new Bitmap(_file);

我想从:

MemoryStream _ms = new MemoryStream();

System.Runtime.InteropServices.Marshal.Copy(RawOriginal.Scan0, SpriteBytes, 0, origByteCount);

使用所需的任何转换无需写入位图。

【问题讨论】:

  • 为什么不使用 FileStream?我猜你是说你没有内存空间,但文件系统上有空间?
  • @CrazyDart 嗨,感谢您的回复。最终的问题是将这个较大图像的部分提取为较小的图像(又名 Sprite)。我不知道这是否可以使用文件流。不过谢谢你的想法......

标签: c# bytearray bitmapdata compact-framework2.0


【解决方案1】:

您要问的问题会很困难。您从响应对象接收的数据是一个完整的 jpeg 图像,它有一个标题,然后是一堆压缩数据字节。 Scan0 寻址的字节数组是未压缩的,很可能在每条扫描线的末尾包含一些填充字节。

最重要的是,您绝对不能使用Marshal.Copy 将接收到的字节复制到Scan0

要执行您的要求,您需要解析收到的 jpeg 的标头并将图像位直接解压缩为 Scan0,并根据需要填充每个扫描线。 .NET Framework 中没有任何东西可以为您做到这一点。

this question 的已接受答案有一个指向可能对您有所帮助的库的链接。

即使这样可行,我也不确定它是否会对您有所帮助。如果调用BitMap 构造函数来创建图像会导致内存不足,那么几乎可以肯定这种迂回方法也会。

问题是你有这么多精灵,你不能把它们全部保存在内存中,未压缩?如果是这样,您可能必须找到其他方法来解决您的问题。

顺便说一句,您可以通过将读取图像的代码更改为:

    MemoryStream _ms = new MemoryStream();
    using (Stream _response = ((HttpWebResponse)_request.GetResponse()).GetResponseStream())
    {
        _response.CopyTo(_ms);
    }

【讨论】:

  • 您好 Jim,感谢您抽出宝贵时间提供帮助。问题是处理大图像会导致内存不足异常,尤其是在移动设备上。我正在使用精灵来包含您看到的视频帧。当我需要从字节数组派生的图像时,我将显示图像,而不是像在网站中使用 div 那样裁剪位置。解决方案是使用一系列较小的图像/精灵,从字节数组中删除标题(等)或/并在服务器上转换为 bitmpdata,因为对大图像的容忍度更高。
  • 对我来说不幸的是,紧凑型 cf 中没有 copyto 方法 :(。在接受你的答案之前,我会先让这个问题继续下去,尽管我确信这很难实现。
  • 嗨,还有两件事。你知道这个库是否可以加载和压缩现有的 jpeg 吗?如果是这样,您是否有示例代码,因为我发现很难在下载中找到示例,因为没有“入门”的东西。虽然这不是我最初的问题,但我会认为你分享你所拥有的任何知识是件好事?谢谢
  • @AndrewSimpson:我对那个库一无所知。看起来它可能对你有帮助。
  • 如果有人在发送到移动设备之前跟踪此转换为位图数据是一个坏主意,因为 jpeg 是未压缩的,并且字节数组太大而无法在 CF 中使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-14
  • 1970-01-01
  • 1970-01-01
  • 2011-07-17
  • 2015-02-11
  • 2011-09-30
  • 1970-01-01
相关资源
最近更新 更多