[.Net] C#์์ JPEG, PNG๋ฅผ WebP๋ก ๋ณํํ๋ ๋ฐฉ๋ฒ (์์ ํฌํจ)
WebP(์นํผ)๋?
C#์์ WebP ๋ณํ ๋ฐฉ๋ฒ์ ์๊ฐํ๊ธฐ์ ์์, WebP๊ฐ ๋ฌด์์ธ์ง๋ถํฐ ์์๋ณด๊ฒ ์ต๋๋ค. WebP๋ ๊ตฌ๊ธ์์ ๋ง๋ ์ด๋ฏธ์ง ํฌ๋งท์ ๋๋ค(WebP๋ ์นํผ๋ผ๊ณ ์ฝ์ต๋๋ค). WebP์ ์ค๋ช ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
WebP(์นํผ, weppy)๋ ์์ค/๋น์์ค ์์ถ ์ด๋ฏธ์ง ํ์ผ์ ์ํ ์ด๋ฏธ์ง ํฌ๋งท์ด๋ค. On2 ํ ํฌ๋๋ฌ์ง์ค์ ๊ธฐ์ ์ ๊ตฌ๋งคํ์ฌ, ๊ทธ๊ฒ์ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ๊ธ์ด ๊ฐ๋ฐํ์ฌ, 2010๋ 9์ 30์ผ ๊ณต๊ฐํ์๋ค. ์์ ํฌ๋งท์ธ VP8์ ํ์์ผ๋ก, ๋ฉํฐ๋ฏธ๋์ด๋ฅผ ๋ด๋ ํฌ๋งท์ธ WebM์ ์๋งค ํ๋ก์ ํธ์ด๋ค. - ์ํค๋ฐฑ๊ณผ
๋ถ์ฐ ์ค๋ช ์ ํ์๋ฉด, WebP ํฌ๋งท์ ์ผ๋ฐ์ ์ผ๋ก ๋ง์ด ์ฌ์ฉ๋๋ JPEG, PNG์ ๊ฐ์ ํฌ๋งท์ ๋์ฒดํ๊ธฐ ์ํด ๊ฐ๋ฐ๋ ๊ฒ์ธ๋ฐ์. ๊ธฐ์กด ํฌ๋งท ๋๋นํ์ฌ ์์ถ๋ฅ ์ ๋์ฑ ์ข์์ง๊ณ ๋น์ทํ ํ์ง์ ์ ์งํ ์ ์๋ค๊ณ ํฉ๋๋ค.
๊ตฌ๊ธ์ ์๋ง์ ๊ฒ์ ๊ฒฐ๊ณผ๋ค์ ๋ณด์ฌ์ฃผ๋๋ฐ, ๊ฐ ํ์ด์ง๋ง๋ค ์ด๋ฏธ์ง ํฌ๋งท์ WebP๋ก ๋์ฒดํ๋ค๋ฉด ์๋ฒ ํธ๋ํฝ์ด ์๋นํ ๋ง์ด ์ค์ด๋ค๊ฒ ๋ฉ๋๋ค. ๊ฒฐ๊ตญ ํธ๋ํฝ๋ ๋น์ฉ์ด๊ธฐ ๋๋ฌธ์, ๊ตฌ๊ธ์ ๋น์ฉ ์ ๊ฐ์ ์ํด ์ด๋ฌํ ํฌ๋งท์ ๋ง๋ ๊ฒ์ด ์๋๊ฐ ํ๋ ์๊ฐ์ด ๋ค๊ฒ ๋ฉ๋๋ค.
WebP Library ์ฐธ๊ณ ์ฌ์ดํธ
WebP ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ดํ ์๋ฃ๋ ์๋ ํํ์ด์ง์์ ์ฐธ๊ณ ํ ์ ์์ต๋๋ค.
https://developers.google.com/speed/webp
WebP์ ๊ดํ ์๊ฐ์ API๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํด์ผ ํ๋์ง์ ๋ํ ์ค๋ช , ๊ทธ๋ฆฌ๊ณ ์ต์ ์ ๋ฐ๋ฅธ ์ด๋ฏธ์ง ์ค๋ช ์ด ํฌํจ๋์ด ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ .Net์์ ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก WebP ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฐ์ผ libwebp-net
๋ ์ ๊ณตํฉ๋๋ค.
https://github.com/imazen/libwebp-net
์ฐธ๊ณ ๋ก NuGet์์๋ Imazen.WebP
๋ฅผ ์ ๊ณตํ๊ณ ์์ต๋๋ค.
ํ์ง๋ง Imazen.WebP
๋ ์ฝ 4๋
์ ์ ์
๋ฐ์ดํธํ ์ดํ ๋ ์ด์ ์
๋ฐ์ดํธ๊ฐ ์ด๋ค์ง์ง ์๊ณ ์์ต๋๋ค. ๊ฒ๋ค๊ฐ SimpleEncoder
๊ฐ์ฒด์ Encode
ํจ์ ํธ์ถ ์ 'GDI+ ์ผ๋ฐ ์ค๋ฅ'๊ฐ ๋ฐ์ํ์ฌ ํด๊ฒฐ์ฑ
์ ์ฐพ์ง ๋ชปํ์ต๋๋ค.
๊ทธ๋์ ๋ณธ๋ฌธ์์๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก C#์์ WebP Library๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์๊ฐํฉ๋๋ค.
libwebp.dll๋ก C#์์ WebP ๋ณํํ๊ธฐ
์์์ ์ธ๊ธํ ๊ฒ์ฒ๋ผ, Imazen.WebP ์ฌ์ฉ ์ GDI+ ์ผ๋ฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋๋ฐ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฐพ์ง ๋ชปํ์ต๋๋ค. ์๋ฌด๋ฆฌ ๊ฒ์ํด๋ ๋์ค์ง ์๋๊ตฐ์. ๊ทธ๋์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก, libwebp.dll
์ P/Invoke
๋ฐฉ์์ผ๋ก ํธ์ถํ๋ ๋ฐฉ๋ฒ์ ์ ํํ์ต๋๋ค.
C#์์ P/Invoke ๋ฐฉ์์ผ๋ก ํธ์ถํ๊ธฐ ์ํด, ๋ค์์ libwebp.dll
์ ๋ค์ด๋ก๋ํฉ๋๋ค. ์๋์ ํ์ผ์ Imazen.WebP
GitHub์ ๋ค์ด๋ก๋ ์ฃผ์๊ฐ ๊ธฐ์ฌ๋์ด ์์ต๋๋ค.
๋ง์ฝ, ์ ๋งํฌ์ ํ์ผ์ด ๋ค์ด๋ก๋๋์ง ์๋๋ค๋ฉด ์๋์ ํ์ผ์ ๋ค์ด๋ก๋ํ์ธ์.
ํ์ผ์ ๋ค์ด๋ก๋ ํ ํ ํ๋ก์ ํธ ๊ฒฝ๋ก์ ๋ถ์ฌ ๋ฃ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ํ๋ก์ ํธ ํ์ผ์ ์ถ๊ฐํฉ๋๋ค.
์ถ๊ฐ๋ dll ํ์ผ์ ์์ฑ์์ ์ถ๋ ฅ ๋๋ ํฐ๋ฆฌ์ ๋ณต์ฌ ํญ๋ชฉ์ ํญ์ ๋ณต์ฌ๋ก ์ ํํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ WebP.cs
ํ์ผ์ ์์ฑํ๊ณ ์๋์ ์ฝ๋๋ฅผ ์
๋ ฅํฉ๋๋ค.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
namespace ExamWebPConverter
{
class WebP
{
[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);
public void SaveLossy(Bitmap bmp, string path, int quality)
{
byte[] arrayWebP = null;
EncodeLossy(bmp, out arrayWebP, quality);
File.WriteAllBytes(path, arrayWebP);
}
private void EncodeLossy(Bitmap bmp, out byte[] arrayWebP, int quality)
{
IntPtr unmanagedPtr;
BitmapData dataBitmap = null;
dataBitmap = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
int size = WebPEncodeBGR(dataBitmap.Scan0, bmp.Width, bmp.Height, dataBitmap.Stride, quality, out unmanagedPtr);
arrayWebP = new byte[size];
Marshal.Copy(unmanagedPtr, arrayWebP, 0, size);
bmp.UnlockBits(dataBitmap);
WebPFree(unmanagedPtr);
}
public void SaveLossless(Bitmap bmp, string path)
{
byte[] arrayWebP = null;
EncodeLossless(bmp, out arrayWebP);
File.WriteAllBytes(path, arrayWebP);
}
private void EncodeLossless(Bitmap bmp, out byte[] arrayWebP)
{
IntPtr unmanagedPtr;
BitmapData dataBitmap = null;
dataBitmap = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
int size = WebPEncodeLosslessBGR(dataBitmap.Scan0, bmp.Width, bmp.Height, dataBitmap.Stride, out unmanagedPtr);
arrayWebP = new byte[size];
Marshal.Copy(unmanagedPtr, arrayWebP, 0, size);
bmp.UnlockBits(dataBitmap);
WebPFree(unmanagedPtr);
}
}
}
SaveLossy
๋ ์์ค ์์ถ์, SaveLossless
๋ ๋ฌด์์ค ์์ถ์ ์๋ฏธํฉ๋๋ค. ๊ฐ ํจ์์ ๋์์ Bitmap์ผ๋ก ์
๋ ฅ๋ฐ์ ํ์ผ์ WebP ํ์ผ๋ก ์ ์ฅํฉ๋๋ค. ์ฐธ๊ณ ๋ก, ์ ์ฝ๋๋ WebP๋ก Encode
ํ๋ API๋ง ์ ์ํ ๊ฒ์
๋๋ค. ๋ฐ๋๋ก WebP๋ฅผ Decode
ํ๋ API๋ ์ ์ํ๋ฉด WebP๋ฅผ PNG๋ก ๋ณํํ ์ ์์ต๋๋ค.
์ ์ฝ๋๋ฅผ ์๋์ ๊ฐ์ด ํธ์ถํ์ฌ ์ฌ์ฉํ ์ ์์ต๋๋ค.
private void buttonConvert_Click(object sender, EventArgs e)
{
try
{
WebP w = new WebP();
Bitmap bmp = new Bitmap(@"../../../image/1.jpg");
w.SaveLossy(bmp, @"../../../image/1_lossy.webp", 75);
w.SaveLossless(bmp, @"../../../image/1_lossless.webp");
}
catch(Exception exc)
{
MessageBox.Show(exc.Message);
}
}
์์ธํ ๋ด์ฉ์ ์๋ ์ํ ์ฝ๋๋ฅผ ์ฐธ๊ณ ํ์ธ์.
'Programming > .Net' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋ค๋ฅธ ๊ธ
-
[.Net] C# WinForm์์ ์ฌ๋ผ์ด๋ฉ ๋ฉ๋ด(Sliding menu), ์ฌ์ด๋๋ฐ(Sidebar) ์ฝ๊ฒ ๋ง๋ค๊ธฐ (์์ ํฌํจ)
[.Net] C# WinForm์์ ์ฌ๋ผ์ด๋ฉ ๋ฉ๋ด(Sliding menu), ์ฌ์ด๋๋ฐ(Sidebar) ์ฝ๊ฒ ๋ง๋ค๊ธฐ (์์ ํฌํจ)
2021.09.26 -
[.Net] C#์์ CefSharp์ผ๋ก ํฌ๋กฌ ๋ธ๋ผ์ฐ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ (์์ ํฌํจ)
[.Net] C#์์ CefSharp์ผ๋ก ํฌ๋กฌ ๋ธ๋ผ์ฐ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ (์์ ํฌํจ)
2021.09.11 -
[.Net] C# Syntax Highlighting ์๋ํฐ๋ฅผ ์ํ ScintillaNET ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
[.Net] C# Syntax Highlighting ์๋ํฐ๋ฅผ ์ํ ScintillaNET ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
2021.08.05 -
[.Net] C#์์ ์์ (Excel) ํ์ผ ๋ค๋ฃจ๋ ๋ฐฉ๋ฒ (์์ ํฌํจ)
[.Net] C#์์ ์์ (Excel) ํ์ผ ๋ค๋ฃจ๋ ๋ฐฉ๋ฒ (์์ ํฌํจ)
2021.05.01