티스토리 블로그 점수가 너무 낮아서 개선사항을 보니 이미지 포맷을 차세대 포맷으로 사용하면 좋다고 합니다. 차세대 이미지 포맷 중 WebP라는 포맷을 사용해보려고 했는데 은근히 변환이 까다롭습니다. 그래서 C#으로 구현하기 위해 방법을 찾아보고 공유합니다.
✅ libwebp.dll를 사용한 WebP 변환
구글에서 제공하는 WebP 라이브러리를 사용합니다. (WebP이 구글에서 만든 포맷입니다.)
libwebp.dll라이브러리는 C또는 C++로 만들어진 라이브러리이기 때문에 P/Invoke 방식으로 사용할 수 있습니다.
DllImport
[DllImport("libwebp.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int WebPEncodeBGR(
IntPtr ptrIn, int width, int height, int stride, float quality, out IntPtr ptrOut);
[DllImport("libwebp.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int WebPEncodeLosslessBGR(
IntPtr ptrIn, int width, int height, int stride, out IntPtr ptrOut);
[DllImport("libwebp.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int WebPFree(
IntPtr ptr);
라이브러리를 출력 경로에 복사한 뒤 DllImport로 사용할 준비를 합니다.
Convert
/// <summary>
/// WebP 변환 함수
/// </summary>
/// <param name="bmp">원본 이미지</param>
/// <param name="path">출력 경로</param>
/// <param name="isLossless">무손실 여부</param>
/// <param name="quality">손실 변환일 경우 품질 (1~100)</param>
public void Convert(Bitmap bmp, string path, bool isLossless, int quality = 100)
{
int size = 0;
IntPtr unmanagedPtr;
byte[]? output = null;
var dataBitmap = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
if (!isLossless)
{
size = WebPEncodeBGR(
dataBitmap.Scan0,
bmp.Width, bmp.Height, dataBitmap.Stride,
quality, out unmanagedPtr);
}
else
{
size = WebPEncodeLosslessBGR(
dataBitmap.Scan0,
bmp.Width, bmp.Height, dataBitmap.Stride,
out unmanagedPtr);
}
if (size != 0)
{
output = new byte[size];
Marshal.Copy(unmanagedPtr, output, 0, size);
bmp.UnlockBits(dataBitmap);
WebPFree(unmanagedPtr);
File.WriteAllBytes(path, output);
}
}
무손실 변환을 제공합니다.
함수가 나뉘어져 있기 때문에 선택할 수 있게 합니다.
매개변수
- bmp : 원본 이미지는 Bitmap 클래스로 전달합니다.
- path : 변환 결과물의 출력 경로입니다.
- quality : 1~100 사이의 값을 가지며 100 이상일 경우는 무손실인 듯합니다만 라이브러리 소스코드를 확인해보진 않았습니다.
- isLossless : true일 경우 WebPEncodeLosslessBGR 함수로 무손실 변환을 수행합니다.
결과
파일 크기가 상당히 줄어드는 결과를 보여줬습니다.
아래 링크에서 윈도우 S/W로 구현한 결과물을 확인하실 수 있습니다.
도움이 되셨다면 커피 한 잔~!
✅ libwebp.dll를 사용한 WebP 변환 - 끝