본문 바로가기

Development/C#

C# 썸네일 생성 참고자료

Written by Youngil Kim, C#.NET Developer

이번에는 System.Drawing.Image클래스에 있는 GetThumbnailImage메소드에 의해서 썸네일이미지를 만드는 방법을 소개할까 합니다.

이전에 팁으로 소개한 이미지파일을 빨리 읽는 방법을 소개한 적이 있는데 이번에는 그때 방법을 좀더 활용하는 케이스로서 FromStream메소드와 GetThumbnailImage메소드를 사용하여 만들어보겠습니다. 또한, Exif정보로부터 썸네일이미지를 얻는 방법도 알아보겠습니다.

- FromFile 메소드 + GetThumbnailImage 메소드

이 예제는 C:\TEMP에 있는 JPEG이미지를 순서대로 읽어 Image객체를 만들고 이를 통해 120*100픽셀의 썸네일이미지를 만들어 파일로 저장합니다. 모든 처리에 관련된 시간체크는 Stopwatch클래스로 측정합니다.

참고로 최근 디지탈카메라로 찍은 JPEG이미지는 사이즈의 썸네일이미지 Exif정보를 가지고 있을 것입니다.

[BasicThumbnail.cs]

using System;
using System.Collections.Generic;
using System.IO;
using System.Drawing;
using System.Diagnostics;

namespace BasicThumbnail
{
class Program
{
static void Main(string[] args)
{
string dir = @"C:\Temp";
string[] jpgfile = Directory.GetFiles(dir, "*.jpg");

Stopwatch sw = Stopwatch.StartNew();

foreach(string jpg in jpgfile)
{
Console.WriteLine(jpg);
Image org = Image.FromFile(jpg);

Image tn = org.GetThumbnailImage(120, 100, delegate { return false; },

IntPtr.Zero);

tn.Save("thumb_"+ Path.GetFileName(jpg),

System.Drawing.Imaging.ImageFormat.Jpeg);

org.Dispose();
tn.Dispose();
}

sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds +"ms");
}

}
}

테스트에 사용한 이미지는 총 13개였고 총 용량은 5.7MB이고 사용한 PC사양은 Intel Core2Duo 1.8Ghz, RAM 3GB였습니다. 이미지 변환테스트시 약 1605ms가 걸렸습니다.

- FromStream메소드 + GetThumbnailImage메소드

이번 예제는 Image클래스의 FromStream메소드를 이용해서 썸네일이미지를 만들어보겠습니다.

[FastThumbnail.cs]

using System;
using System.Collections.Generic;
using System.IO;
using System.Drawing;
using System.Diagnostics;

namespace FastThumbnail
{
class Program
{
static void Main(string[] args)
{
string dir = @"C:\Temp";
string[] jpgfile = Directory.GetFiles(dir, "*.jpg");

Stopwatch sw = Stopwatch.StartNew();

foreach(string jpg in jpgfile)
{
Console.WriteLine(jpg);
using (FileStream fs = File.OpenRead(jpg)) {
Image org = Image.FromStream(fs, false, false);

Image tn = org.GetThumbnailImage(120, 100, delegate { return false; },

IntPtr.Zero);
tn.Save("thumb2_"+Path.GetFileName(jpg),

System.Drawing.Imaging.ImageFormat.Jpeg);

org.Dispose();
tn.Dispose();
}
}

sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds +"ms");

}
}
}
걸린시간: 227ms

FromStream메소드는 파일전체를 읽지 않으며 일반적인 썸네일 이미지는 JPEG파일 앞부분에 저장되어 있기 때문에 앞서 테스트한 예제보다 7배정도 빠른 속도로 개선되었습니다.

- Exif정보에서 썸네일 이미지 읽어내는 방법

JPEG파일의 Exif정보에 저장되어 있는 썸네일 이미지 데이터(태그번호 0x501b)를 바이트배열로 얻어 썸네일 이미지를 만드는 방법을 소개하겠습니다.

[ExifThumbnail.cs]

using System;
using System.Collections.Generic;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Diagnostics;

namespace ExifThumbnail
{
class Program
{
static void Main(string[] args)
{
string dir = @"C:\Temp";
string[] jpgfile = Directory.GetFiles(dir, "*.jpg");

ImageConverter ic = new ImageConverter();

Stopwatch sw = Stopwatch.StartNew();

foreach(string jpg in jpgfile) {
Console.WriteLine(jpg);

using(FileStream fs = File.OpenRead(jpg))
{
Image org = Image.FromStream(fs, false, false);

int[] pi = org.PropertyIdList;
int index = Array.IndexOf(pi, 0x501b); // 썸네일 데이터

if(index==-1) {
Console.WriteLine("이미지에 썸네일정보가 없습니다!");
} else {
PropertyItem p = org.PropertyItems[index];
byte[] jpgbytes = p.Value;

Image tn = (Image)ic.ConvertFrom(jpgbytes);

tn.Save("thumb3_"+Path.GetFileName(jpg),

System.Drawing.Imaging.ImageFormat.Jpeg);
tn.Dispose();
}
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds +"ms");
}
}
}
}

이미지당 17ms걸리고 총 13개이미지변환느데 221ms가 걸리네요

GOM환경에서는 위 예제로들로 약 16배 고속으로 썸네일 이미지를 생성할 수 있습니다. 물론 사람마다 사용하는 환경 및 JPEG이미지에 따라 조금씩은 틀릴 수 있습니다.

단, Exif정보내에 썸네일정보가 없는 경우 만들 수 없기때문에, 2번째 프로그램과 3번째 프로그램을 혼합하여 썸네일을 만들어주는 프로그램을 활용하면 괜찮은 코어가 나오겠죠?

그건 여러분들의 필요하신 실무에 활용해보세요! ^^;



출처: https://pjm187.tistory.com/21 [FusionWiz의 스토리]