ASP.NET Core에서 이미지를 처리하려면 제3사 도구인 SixLabors가 필요하다.
(RC버전이 나올 무렵에 받아서 v1.0.0-rc0001 버전을 쓰고 있었다.)
최근에 본의 아니게 이 SixLabors 이미지 관련 툴을 최신 버전으로 업데이트하게 되었는데...
알고 보니 툴 버그가 아니었고... 굳이 업데이트할 필요까지는 없었다.
뭐, 최신 안정화 버전으로 업데이트했으니, 헛수고를 한 것은 아니지만.
>> 참조: www.nuget.org/packages/SixLabors.ImageSharp.Web/1.0.1
문제는... JPG 이미지를 업로드하는데, 아래와 같은 오류가 발생하는 것이었다.
Image cannot be loaded. Available decoders: GIF : GifDecoder PNG : PngDecoder JPEG : JpegDecoder BMP : BmpDecoder |
분명히 JPEG 포맷이 맞는데, 지원되지 않는다니...
아래 코드에서 대체 무슨 문제가 있었을까?
private static bool isValidImage(string filePath)
{
if (!File.Exists(filePath))
{
Debug.WriteLine("isValidImage(): !File.Exists");
return false;
}
using (FileStream imageStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
if (imageStream.Length <= 0)
{
Debug.WriteLine("isValidImage(): imageStream.Length <= 0");
return false;
}
byte[] bmp = Encoding.ASCII.GetBytes("BM"); // BMP
byte[] gif = Encoding.ASCII.GetBytes("GIF"); // GIF
byte[] png = new byte[] { 137, 80, 78, 71 }; // PNG
byte[] tiff = new byte[] { 73, 73, 42 }; // TIFF
byte[] tiff2 = new byte[] { 77, 77, 42 }; // TIFF
byte[] jpeg = new byte[] { 255, 216, 255, 224 }; // jpeg
byte[] jpeg2 = new byte[] { 255, 216, 255, 225 }; // jpeg canon
byte[] header = new byte[4]; // Change size if needed.
imageStream.Read(header, 0, header.Length);
bool isImageHeader =
bmp.SequenceEqual(header.Take(bmp.Length)) ||
gif.SequenceEqual(header.Take(gif.Length)) ||
png.SequenceEqual(header.Take(png.Length)) ||
tiff.SequenceEqual(header.Take(tiff.Length)) ||
tiff2.SequenceEqual(header.Take(tiff2.Length)) ||
jpeg.SequenceEqual(header.Take(jpeg.Length)) ||
jpeg2.SequenceEqual(header.Take(jpeg2.Length));
if (isImageHeader)
{
try
{
Image.Load(imageStream).Dispose();
imageStream.Close();
return true;
}
catch (Exception ex)
{
Debug.WriteLine("isValidImage(): " + ex.Message);
}
}
else
{
Debug.WriteLine("isValidImage(): ImageHeader is not any of JPEG, BMP, GIF, PNG");
}
}
return false;
}
오류가 발생한 부분은 위 코드의 41번째 줄 Image.Load(imageStream)에서였다.
분명히 JPEG 헤더까지 이상없이 잘 나왔는데, 실제 이미지를 로드하다가 오류가 발생한 것.
그래서 SixLabors 도구의 버전이 낮아서 그런 것인가 의심까지 했었는데... 아니었다.
.
.
.
.
.
.
.
.
문제는 바로 위에 있었다.
26번째 줄 imageStream.Read(header, 0, header.Length); 이 부분.
이미지 포맷을 비교하기 위해 Stream의 첫 부분부터 4바이트를 읽었는데... 4번째로 위치가 바뀌어 있었던 것!
이미지를 정상 로드하려면 Stream의 현재 위치를 맨 처음으로 다시 돌려야 했던 것이다!
imageStream.Position = 0;
Image.Load(imageStream).Dispose();
...
이 코드가 빠져서 발생한 오류였던 것이다. ㄷㄷ
똑같은 실수를 벌써 몇 번째 반복하는 것인지 원.
이번에는 블로그에 글까지 파서 올려 두었으니 다시 실수를 하지는 않겠지? ㅎ
아래 올바른 소스로 다시 써 둔다.
private static bool isValidImage(string filePath)
{
if (!File.Exists(filePath))
{
Debug.WriteLine("isValidImage(): !File.Exists");
return false;
}
using (FileStream imageStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
if (imageStream.Length <= 0)
{
Debug.WriteLine("isValidImage(): imageStream.Length <= 0");
return false;
}
byte[] bmp = Encoding.ASCII.GetBytes("BM"); // BMP
byte[] gif = Encoding.ASCII.GetBytes("GIF"); // GIF
byte[] png = new byte[] { 137, 80, 78, 71 }; // PNG
byte[] tiff = new byte[] { 73, 73, 42 }; // TIFF
byte[] tiff2 = new byte[] { 77, 77, 42 }; // TIFF
byte[] jpeg = new byte[] { 255, 216, 255, 224 }; // jpeg
byte[] jpeg2 = new byte[] { 255, 216, 255, 225 }; // jpeg canon
byte[] header = new byte[4]; // Change size if needed.
imageStream.Read(header, 0, header.Length);
bool isImageHeader =
bmp.SequenceEqual(header.Take(bmp.Length)) ||
gif.SequenceEqual(header.Take(gif.Length)) ||
png.SequenceEqual(header.Take(png.Length)) ||
tiff.SequenceEqual(header.Take(tiff.Length)) ||
tiff2.SequenceEqual(header.Take(tiff2.Length)) ||
jpeg.SequenceEqual(header.Take(jpeg.Length)) ||
jpeg2.SequenceEqual(header.Take(jpeg2.Length));
if (isImageHeader)
{
try
{
imageStream.Position = 0;
Image.Load(imageStream).Dispose();
imageStream.Close();
return true;
}
catch (Exception ex)
{
Debug.WriteLine("isValidImage(): " + ex.Message);
}
}
else
{
Debug.WriteLine("isValidImage(): ImageHeader is not any of JPEG, BMP, GIF, PNG");
}
}
return false;
}
'Tech: > .NET·C#' 카테고리의 다른 글
웹사이트에서 로컬 C# WinForm 프로그램 실행하기 (0) | 2023.04.03 |
---|---|
Visual Studio 2019 ASP.NET Core 하위 호환성 문제 (0) | 2021.01.07 |
ASP.NET Core Html Helper? Tag Helper! (0) | 2020.12.08 |
PushSharp: FCM/APNs Push 팁 (0) | 2019.05.17 |
VS2017 환경과 .NET Framework 4.7.1 타기팅 팩 (0) | 2019.05.10 |