在网络上获取图像的尺寸 - 如何避免内存占用?

4

我正在从指定的URL获取一些网页图片,我想要获取它们的高度和宽度。我使用类似以下的代码:

 Stream str = null;
 HttpWebRequest wReq = (HttpWebRequest)WebRequest.Create(ImageUrl);
 HttpWebResponse wRes = (HttpWebResponse)(wReq).GetResponse();
 str = wRes.GetResponseStream();

 var imageOrig = System.Drawing.Image.FromStream(str);
 int height = imageOrig.Height;
 int width = imageOrig.Width;

我的主要担忧是图像文件可能非常大,

我该怎么办?例如只获取小于1mb的图像吗? 或者有更好的方法来从网页中获取图像的尺寸吗?

谢谢

4个回答

5

一些(或全部)图像格式在文件头中包含宽度和高度属性。您可以请求足够的字节数以便读取文件头,然后自己解析它们。您可以在web请求中添加一个范围头,该范围头将仅请求图像文件的前50个字节(50只是一个示例,您可能需要更少):

wReq.AddRange(0, 50);

我想这只有在您知道您正在使用的格式包括这些数据时才能起作用。

编辑:看起来我之前误解了AddRange方法。现在已经修复了。我还通过使用这个文档获取png的宽度和高度进行了测试。

static void Main(string[] args)
{
    string imageUrl = "http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png";
    byte[] pngSignature = new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 };
    HttpWebRequest wReq = (HttpWebRequest)WebRequest.Create(imageUrl);
    wReq.AddRange(0, 30);
    WebResponse wRes = wReq.GetResponse();
    byte[] buffer = new byte[30];
    int width = 0;
    int height = 0;

    using (Stream stream = wRes.GetResponseStream())
    {
        stream.Read(buffer, 0, 30);
    }

    // Check for Png
    // 8 byte - Signature
    // 4 byte - Chunk length
    // 4 byte - Chunk type - IDHR (Image Header)
    // 4 byte - Width
    // 4 byte - Height
    // Other stuff we don't care about
    if (buffer.Take(8).SequenceEqual(pngSignature))
    {
        var idhr = buffer.Skip(12);
        width = BitConverter.ToInt32(idhr.Skip(4).Take(4).Reverse().ToArray(), 0);
        height = BitConverter.ToInt32(idhr.Skip(8).Take(4).Reverse().ToArray(), 0);
    }
    // Check for Jpg
    //else if (buffer.Take(?).SequenceEqual(jpgSignature))
    //{
    //    // Do Jpg stuff
    //}
    // Check for Gif
    //else if (etc...

    Console.WriteLine("Width: " + width);
    Console.WriteLine("Height: " + height);
    Console.ReadKey();
}

Someone Somewhere的帖子展示了如何识别jpg和gif格式的图片。 - Chris

3
只需要从图形文件中下载头文件即可找到图片大小,具体方法如下:
BMP格式:(只需26个字节) http://www.fileformat.info/format/bmp/corion.htm JPG格式:(查找“Star of Frame”标记) http://wiki.tcl.tk/757 GIF格式:(只需10个字节,即逻辑屏幕描述符的前两个单词) http://www.matthewflickinger.com/lab/whatsinagif/bits_and_bytes.asp 此外,请注意您可以读取前几个字节以查找文件类型(不要依赖文件名扩展名。例如,bmp文件可能会因为错误而命名为“.gif”。一旦您知道了文件类型,您就可以查看规范以了解要读取的偏移量。
附:获取十六进制编辑器(例如“Hex Editor XVI32”),以查看文件结构。 您可以在此处下载XVI32:http://www.chmaas.handshake.de/delphi/freeware/xvi32/xvi32.htm

1

你可能想编写一个 Web 服务,其中给定输入图像名称,提供大小作为响应。

根据结果值,您可以选择下载图像。

如果您想要比 Web 服务更轻量级的东西,请选择 HTTP 处理程序。


0
您可以尝试使用FileInfo类来查找文件大小。
long fileSizeInKb = new FileInfo(fileName).Length / 1000;
if (fileSizeInKb < 1000)
{
  // get image
}

Length 属性返回当前文件中的字节数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接