使用Web客户端获取远程图像生成木纹GIF和不能处理PNG + BMP [英] Using WebClient to get Remote Images Produces Grainy GIFs and Can't Handle PNG+BMP

查看:125
本文介绍了使用Web客户端获取远程图像生成木纹GIF和不能处理PNG + BMP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好!

我创建一个Web表单原型(ImageLaoder.aspx),将返回一个图像,使其可以像这样简单的例子可以使用其他Web窗体/网页:

I'm creating a web form prototype (ImageLaoder.aspx) that will return an image so that it may be used like this simple example other Web Forms/web pages:

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

到目前为止,它加载的JPG文件,没有任何问题,但GIF文件相比初代吸血鬼和骨形成蛋白和PNG图像导致以下异常期待颗粒的:

So far, it loads JPGs with no problems, however GIFs look "grainy" compared to the orignals and BMPs and PNGs result in the following exception:

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

System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+

我的code到目前为止是这样的:

My code thus far looks like this:

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, 0, l_imageBytes.Length))
    {
        l_MemStream.Write(l_imageBytes, 0, 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的和导致异常?

Any ideas why GIFs are grainy and PNGs and BMPs cause exceptions?

推荐答案

你的getImage方法的几点:

A few points about your GetImage method:


  • 当你使用Image.FromStream你不应该关闭(或处置)的流

  • 如果你在一个流调用Dispose(使用using语句),你不需要调用Close

  • 您正在编写到流,但不是倒带它,所以l_image实际上并没有得到任何的数据,据我所看到的(除非Image.FromStream重置本身的位置)。 (这可能是因为GIF / JPG德codeRS倒带流,但BMP / PNG没有,因此错误。)

  • 你为什么不只是使用的MemoryStream构造函数,它接受一个字节数组?

总之,我相信你的getImage方法可以替换为:

In short, I believe your GetImage method can be replaced with:

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);
}

现在,更重要的是 - 你为什么加载图像呢?你为什么不只是服务于文件本身作为响应,设定为你已经做的内容类型 - 或可能只是基于扩展?换句话说,所有的code会变成:

Now, more importantly - why are you loading the image at all? Why don't you just serve the file itself as a response, setting the content type as you're already doing - or possibly just based on the extension? In other words, all of your code would become:

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, 0, data.Length);
    Response.End();
}

多一点错误处理(包括这是一个合理的扩展?)将是很好的,但除此之外,我认为这没关系。的实际加载自己的形象,唯一的好处是,你能验证它确实的图像,而不是病毒或类似的东西。

A bit more error handling (including "is this a reasonable extension?") would be nice, but other than that I think it's okay. The only benefit of actually loading the image yourself is that you get to validate that it really is an image rather than a virus or something like that.

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

Just out of interest, do you have a good reason why you'd want image requests to go through your server? Why would the web page author write:

<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" />

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

There are some reasons why it might be useful, but in many cases it's just a waste.

这篇关于使用Web客户端获取远程图像生成木纹GIF和不能处理PNG + BMP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆