첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.

728x90
반응형
728x170

TestProject.zip
4.18MB

▶ WEBPHelper.cs

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// WEBP 헬퍼
    /// </summary>
    public static class WEBPHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Import
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region WEBP BGR 인코딩하기 - WebPEncodeBGR(sourceDataHandle, width, height, stride, quality, targetDataHandle)

        /// <summary>
        /// WEBP BGR 인코딩하기
        /// </summary>
        /// <param name="sourceDataHandle">소스 데이터 핸들</param>
        /// <param name="width">너비</param>
        /// <param name="height">높이</param>
        /// <param name="stride">보폭</param>
        /// <param name="quality">품질</param>
        /// <param name="targetDataHandle">타겟 데이터 핸들</param>
        /// <returns>타겟 데이터 바이트 길이</returns>
        [DllImport("libwebp", CallingConvention = CallingConvention.Cdecl)]
        private static extern int WebPEncodeBGR
        (
            IntPtr     sourceDataHandle,
            int        width,
            int        height,
            int        stride,
            float      quality,
            out IntPtr targetDataHandle
        );

        #endregion
        #region WEBP BGR 인코딩하기 (무손실) - WebPEncodeLosslessBGR(sourceDataHandle, width, height, stride, targetDataHandle)

        /// <summary>
        /// WEBP BGR 인코딩하기 (무손실)
        /// </summary>
        /// <param name="sourceDataHandle">소스 데이터 핸들</param>
        /// <param name="width">너비</param>
        /// <param name="height">높이</param>
        /// <param name="stride">보폭</param>
        /// <param name="targetDataHandle">타겟 데이터 핸들</param>
        /// <returns>타겟 데이터 바이트 길이</returns>
        [DllImport("libwebp", CallingConvention = CallingConvention.Cdecl)]
        private static extern int WebPEncodeLosslessBGR(IntPtr sourceDataHandle, int width, int height, int stride, out IntPtr targetDataHandle);

        #endregion
        #region WEBP 해제하기 - WebPFree(targetDataHandle)

        /// <summary>
        /// WEBP 해제하기
        /// </summary>
        /// <param name="targetDataHandle">타겟 데이터 핸들</param>
        /// <returns>처리 결과</returns>
        [DllImport("libwebp", CallingConvention = CallingConvention.Cdecl)]
        private static extern int WebPFree(IntPtr targetDataHandle);

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 저장하기 - Save(sourceBitmap, targetFilePath, quality)

        /// <summary>
        /// 저장하기
        /// </summary>
        /// <param name="sourceBitmap">소스 비트맵</param>
        /// <param name="targetFilePath">타겟 파일 경로</param>
        /// <param name="quality">품질</param>
        public static void Save(Bitmap sourceBitmap, string targetFilePath, int quality)
        {
            Convert(sourceBitmap, out byte[] targetByteArray, quality);

            File.WriteAllBytes(targetFilePath, targetByteArray);
        }

        #endregion
        #region 저장하기 (무손실) - Save(sourceBitmap, targetFilePath)

        /// <summary>
        /// 저장하기 (무손실)
        /// </summary>
        /// <param name="sourceBitmap">소스 비트맵</param>
        /// <param name="targetFilePath">타겟 파일 경로</param>
        public static void Save(Bitmap sourceBitmap, string targetFilePath)
        {
            Convert(sourceBitmap, out byte[] targetByteArray);

            File.WriteAllBytes(targetFilePath, targetByteArray);
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Public

        #region 변환하기 - Convert(sourceBitmap, targetByteArray, quality)

        /// <summary>
        /// 변환하기
        /// </summary>
        /// <param name="sourceBitmap">소스 비트맵</param>
        /// <param name="targetByteArray">타겟 바이트 배열</param>
        /// <param name="quality">품질</param>
        private static void Convert(Bitmap sourceBitmap, out byte[] targetByteArray, int quality)
        {
            BitmapData sourceBitmapData = sourceBitmap.LockBits
            (
                new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
                ImageLockMode.ReadOnly,
                PixelFormat.Format24bppRgb
            );

            int targetDataByteLength = WebPEncodeBGR
            (
                sourceBitmapData.Scan0,
                sourceBitmap.Width,
                sourceBitmap.Height,
                sourceBitmapData.Stride,
                quality,
                out IntPtr targetHandle
            );

            targetByteArray = new byte[targetDataByteLength];

            Marshal.Copy(targetHandle, targetByteArray, 0, targetDataByteLength);

            sourceBitmap.UnlockBits(sourceBitmapData);

            WebPFree(targetHandle);
        }

        #endregion
        #region 변환하기 - Convert(sourceBitmap, targetByteArray)

        /// <summary>
        /// 변환하기
        /// </summary>
        /// <param name="sourceBitmap">소스 비트맵</param>
        /// <param name="targetByteArray">타겟 바이트 배열</param>
        private static void Convert(Bitmap sourceBitmap, out byte[] targetByteArray)
        {
            BitmapData sourceBitmapData = sourceBitmap.LockBits
            (
                new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
                ImageLockMode.ReadOnly,
                PixelFormat.Format24bppRgb
            );

            int targetDataByteLength = WebPEncodeLosslessBGR
            (
                sourceBitmapData.Scan0,
                sourceBitmap.Width,
                sourceBitmap.Height,
                sourceBitmapData.Stride,
                out IntPtr targetHandle
            );

            targetByteArray = new byte[targetDataByteLength];

            Marshal.Copy(targetHandle, targetByteArray, 0, targetDataByteLength);

            sourceBitmap.UnlockBits(sourceBitmapData);

            WebPFree(targetHandle);
        }

        #endregion
    }
}

 

728x90

 

▶ Program.cs

using System.Drawing;

namespace TestProject
{
    /// <summary>
    /// 프로그램
    /// </summary>
    class Program
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 프로그램 시작하기 - Main()

        /// <summary>
        /// 프로그램 시작하기
        /// </summary>
        private static void Main()
        {
            Bitmap sourceBitmap = new Bitmap("IMAGE\\source.png");

            WEBPHelper.Save(sourceBitmap, "target1.webp", 75);
            WEBPHelper.Save(sourceBitmap, "target2.webp"); // 무손실
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요