WebClient를 사용하여 원격 이미지를 얻는 것은 거친 GIF를 생성하고 png+bmp를 처리 할 수 ​​없습니다.

StackOverflow https://stackoverflow.com/questions/499210

  •  20-08-2019
  •  | 
  •  

문제

인사말!

이 간단한 예제 다른 웹 양식/웹 페이지처럼 사용될 수 있도록 이미지를 반환하는 웹 양식 프로토 타입 (imagelaoder.aspx)을 만들고 있습니다.

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

지금까지 문제가없는 JPG를로드하지만 GIF는 Orignals 및 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, 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가 예외를 일으키는 이유는 무엇입니까?

도움이 되었습니까?

해결책

GetImage 방법에 대한 몇 가지 요점 :

  • 이미지를 사용하면 스트림을 닫거나 폐기하지 않아야합니다.
  • 스트림에 처분을 호출하는 경우 (사용 명세서와 함께) 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, 0, 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" />

거기 ~이다 그것이 유용 할 수있는 몇 가지 이유이지만 많은 경우에 그것은 단지 폐기물 일뿐입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top