WebClient를 사용하여 원격 이미지를 얻는 것은 거친 GIF를 생성하고 png+bmp를 처리 할 수 없습니다.
문제
인사말!
이 간단한 예제 다른 웹 양식/웹 페이지처럼 사용될 수 있도록 이미지를 반환하는 웹 양식 프로토 타입 (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" />
거기 ~이다 그것이 유용 할 수있는 몇 가지 이유이지만 많은 경우에 그것은 단지 폐기물 일뿐입니다.