加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用WebClient获取远程图像会产生粒状GIF,无法处理PNG BMP

发布时间:2020-12-15 19:41:18 所属栏目:百科 来源:网络整理
导读:问候! 我正在创建一个Web表单原型(ImageLaoder.aspx),它将返回一个图像,以便它可以像其他Web表单/网页的简单示例一样使用: img src="http://www.mydomain.com/ImageLoader.aspx?i=http://images.mydomain.com/img/a.jpg" / 到目前为止,它加载JPG没有问题,
问候!

我正在创建一个Web表单原型(ImageLaoder.aspx),它将返回一个图像,以便它可以像其他Web表单/网页的简单示例一样使用:

<img src="http://www.mydomain.com/ImageLoader.aspx?i=http://images.mydomain.com/img/a.jpg" />

到目前为止,它加载JPG没有问题,但是与原始数据相比,GIF看起来“颗粒状”,而BMP和PNG导致以下异常:

System.Runtime.InteropServices.ExternalException:GDI中发生一般错误

到目前为止我的代码看起来像这样:

protected void Page_Load(object sender,EventArgs e)
{
    string l_filePath = Request.QueryString["i"];

    System.Drawing.Image l_image = GetImage(l_filePath);
    if (l_image != null)
    {
        System.Drawing.Imaging.ImageFormat l_imageFormat = DetermineImageFormat(l_filePath);
        WriteImageAsReponse(l_image,l_imageFormat);
    }
}

private System.Drawing.Image GetImage(string filePath)
{
    WebClient l_WebClient = new WebClient();
    byte[] l_imageBytes = l_WebClient.DownloadData(filePath);

    System.Drawing.Image l_image = null;
    using (MemoryStream l_MemStream = new MemoryStream(l_imageBytes,l_imageBytes.Length))
    {
        l_MemStream.Write(l_imageBytes,l_imageBytes.Length);
        l_image = System.Drawing.Image.FromStream(l_MemStream,true);
        l_MemStream.Close();
    }

    return l_image;
}

private System.Drawing.Imaging.ImageFormat DetermineImageFormat(string filePath)
{
    if (filePath.EndsWith(".jpg",StringComparison.OrdinalIgnoreCase))
        return System.Drawing.Imaging.ImageFormat.Jpeg;
    else if (filePath.EndsWith(".gif",StringComparison.OrdinalIgnoreCase))
        return System.Drawing.Imaging.ImageFormat.Gif;
    else if (filePath.EndsWith(".png",StringComparison.OrdinalIgnoreCase))
        return System.Drawing.Imaging.ImageFormat.Png;
    else
        return System.Drawing.Imaging.ImageFormat.Bmp;
}

private void WriteImageAsReponse(System.Drawing.Image image,System.Drawing.Imaging.ImageFormat imageFormat)
{
    if (image == null)
        return;

    System.Drawing.Bitmap l_outputBitMap = new Bitmap(image);

    if (imageFormat == System.Drawing.Imaging.ImageFormat.Jpeg)
        Response.ContentType = "image/jpg";
    else if (imageFormat == System.Drawing.Imaging.ImageFormat.Gif)
        Response.ContentType = "image/gif";
    else if (imageFormat == System.Drawing.Imaging.ImageFormat.Png)
        Response.ContentType = "image/png";
    else
        Response.ContentType = "image/bmp";

    l_outputBitMap.Save(Response.OutputStream,imageFormat);
}

任何想法为什么GIF是颗粒状的,PNG和BMP导致异常?

解决方法

关于GetImage方法的几点:

>使用Image.FromStream时,不应关闭(或处置)流
>如果您在流上调用Dispose(使用using语句),则无需调用Close
>你正在写入流,但后来没有“倒带”,所以l_image实际上并没有我能看到的任何数据(除非Image.FromStream重置位置本身). (可能是gif / jpg解码器倒回流但是bmp / png没有,因此错误.)
>为什么不使用带有字节数组的MemoryStream构造函数?

简而言之,我相信您的GetImage方法可以替换为:

private Image GetImage(string filePath)
{
    WebClient l_WebClient = new WebClient();
    byte[] l_imageBytes = l_WebClient.DownloadData(filePath);
    MemoryStream l_stream = new MemoryStream(l_imageBytes);
    return Image.FromStream(l_stream);
}

现在,更重要的是 – 为什么要加载图像?为什么不将文件本身作为响应提供,设置内容类型就像你已经在做的那样 – 或者可能只是基于扩展名?换句话说,您的所有代码都将成为:

protected void Page_Load(object sender,EventArgs e)
{
    string filePath = Request.QueryString["i"];
    string extension = l_filePath.Substring(l_filePath.LastIndexOf('.') + 1);
    Response.ContentType = "image/" + extension;
    byte[] data = new WebClient.DownloadData(filePath);
    Response.OutputStream.Write(data,data.Length);
    Response.End();
}

更多的错误处理(包括“这是一个合理的扩展吗?”)会很好,但除此之外我觉得没关系.实际加载图像的唯一好处是,您可以验证它确实是图像而不是病毒或类似的东西.

编辑:只是出于兴趣,你有充分的理由为什么你想要图像请求通过你的服务器?为什么网页作者会写:

<img src="http://www.mydomain.com/ImageLoader.aspx?i=http://images.mydomain.com/img/a.jpg" />

代替

<img src="http://images.mydomain.com/img/a.jpg" />

有一些原因可能会有用,但在许多情况下,这只是一种浪费.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读