■ WriteableBitmap 클래스 : 멀티 포맷으로 저장하기

------------------------------------------------------------------------------------------------------------------------


TestProject.zip


WriteableBitmapExtension.cs

 

 

using System.IO;

using System.Windows.Media.Imaging;

 

namespace TestProject

{

    /// <summary>

    /// 쓰기 가능한 비트맵 확장

    /// </summary>

    public static class WriteableBitmapExtension

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Enumeration

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

 

        #region 이미지 포맷 - ImageFormat

 

        /// <summary>

        /// 이미지 포맷

        /// </summary>

        public enum ImageFormat

        {

            /// <summary>

            /// 비트맵

            /// </summary>

            BMP,

 

            /// <summary>

            /// GIF

            /// </summary>

            GIF,

 

            /// <summary>

            /// JPG

            /// </summary>

            JPG,

 

            /// <summary>

            /// PNG

            /// </summary>

            PNG,

 

            /// <summary>

            /// TIFF

            /// </summary>

            TIFF,

 

            /// <summary>

            /// WMP

            /// </summary>

            WMP

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Enumeration

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

 

        #region 저장하기 - Save(writeableBitmap, filePath, imageFormat)

 

        /// <summary>

        /// 저장하기

        /// </summary>

        /// <param name="writeableBitmap">쓰기 가능한 비트맵</param>

        /// <param name="filePath">파일 경로</param>

        /// <param name="imageFormat">이미지 포맷</param>

        public static void Save(this WriteableBitmap writeableBitmap, string filePath, ImageFormat imageFormat)

        {

            using(FileStream stream = new FileStream(filePath, FileMode.Create))

            {

                BitmapEncoder encoder = null;

 

                switch(imageFormat)

                {

                    case ImageFormat.BMP  : encoder = new BmpBitmapEncoder();  break;

                    case ImageFormat.GIF  : encoder = new GifBitmapEncoder();  break;

                    case ImageFormat.JPG  : encoder = new JpegBitmapEncoder(); break;

                    case ImageFormat.PNG  : encoder = new PngBitmapEncoder();  break;

                    case ImageFormat.TIFF : encoder = new TiffBitmapEncoder(); break;

                    case ImageFormat.WMP  : encoder = new WmpBitmapEncoder();  break;

                }

 

                encoder.Frames.Add(BitmapFrame.Create(writeableBitmap));

 

                encoder.Save(stream);

            }

        }

 

        #endregion

        #region 저장하기 - Save(writeableBitmap, filePath)

 

        /// <summary>

        /// 저장하기

        /// </summary>

        /// <param name="writeableBitmap">쓰기 가능한 비트맵</param>

        /// <param name="filePath">파일 경로</param>

        public static void Save(this WriteableBitmap writeableBitmap, string filePath)

        {

            FileInfo fileInfo = new FileInfo(filePath);

 

            switch(fileInfo.Extension.ToLower())

            {

                case ".bmp"  : writeableBitmap.Save(filePath, ImageFormat.BMP ); break;

                case ".gif"  : writeableBitmap.Save(filePath, ImageFormat.GIF ); break;

                case ".jpg"  :

                case ".jpeg" : writeableBitmap.Save(filePath, ImageFormat.JPG ); break;

                case ".png"  : writeableBitmap.Save(filePath, ImageFormat.PNG ); break;

                case ".tif"  :

                case ".tiff" : writeableBitmap.Save(filePath, ImageFormat.TIFF); break;

                case ".wmp"  : writeableBitmap.Save(filePath, ImageFormat.WMP ); break;

            }

        }

 

        #endregion

    }

}

 

 

BitmapHelper.cs

 

 

using System.Windows;

using System.Windows.Media;

using System.Windows.Media.Imaging;

 

namespace TestProject

{

    /// <summary>

    /// 비트맵 헬퍼

    /// </summary>

    public class BitmapHelper

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 너비

        /// </summary>

        private int width;

        

        /// <summary>

        /// 높이

        /// </summary>

        private int height;

 

        /// <summary>

        /// 픽셀 배열

        /// </summary>

        private byte[] pixelArray;

 

        /// <summary>

        /// 스트라이드

        /// </summary>

        /// <remarks>해당 바이트 수이다.</remarks>

        private int stride;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

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

 

        #region 생성자 - BitmapHelper(width, height)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="width">너비</param>

        /// <param name="height">높이</param>

        public BitmapHelper(int width, int height)

        {

            this.width  = width;

            this.height = height;

 

            this.pixelArray = new byte[width * height * 4];

 

            this.stride = width * 4;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

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

 

        #region 픽셀 구하기 - GetPixel(x, y, red, green, blue, alpha)

 

        /// <summary>

        /// 픽셀 구하기

        /// </summary>

        /// <param name="x">X 좌표</param>

        /// <param name="y">Y 좌표</param>

        /// <param name="red">빨간색 채널</param>

        /// <param name="green">녹색 채널</param>

        /// <param name="blue">파란색 채널</param>

        /// <param name="alpha">알파 채널</param>

        public void GetPixel(int x, int y, out byte red, out byte green, out byte blue, out byte alpha)

        {

            int index = y * this.stride + x * 4;

 

            blue  = this.pixelArray[index++];

            green = this.pixelArray[index++];

            red   = this.pixelArray[index++];

            alpha = this.pixelArray[index  ];

        }

 

        #endregion

 

        #region 파란색 채널 구하기 - GetBlue(x, y)

 

        /// <summary>

        /// 파란색 채널 구하기

        /// </summary>

        /// <param name="x">X 좌표</param>

        /// <param name="y">Y 좌표</param>

        /// <returns>파란색 채널</returns>

        public byte GetBlue(int x, int y)

        {

            return this.pixelArray[y * this.stride + x * 4];

        }

 

        #endregion

        #region 녹색 채널 구하기 - GetGreen(x, y)

 

        /// <summary>

        /// 녹색 채널 구하기

        /// </summary>

        /// <param name="x">X 좌표</param>

        /// <param name="y">Y 좌표</param>

        /// <returns>녹색 채널</returns>

        public byte GetGreen(int x, int y)

        {

            return this.pixelArray[y * this.stride + x * 4 + 1];

        }

 

        #endregion

        #region 빨간색 채널 구하기 - GetRed(x, y)

 

        /// <summary>

        /// 빨간색 채널 구하기

        /// </summary>

        /// <param name="x">X 좌표</param>

        /// <param name="y">Y 좌표</param>

        /// <returns>빨간색 채널</returns>

        public byte GetRed(int x, int y)

        {

            return this.pixelArray[y * this.stride + x * 4 + 2];

        }

 

        #endregion

        #region 알파 채널 구하기 - GetAlpha(x, y)

 

        /// <summary>

        /// 알파 채널 구하기

        /// </summary>

        /// <param name="x">X 좌표</param>

        /// <param name="y">Y 좌표</param>

        /// <returns>알파 채널</returns>

        public byte GetAlpha(int x, int y)

        {

            return this.pixelArray[y * this.stride + x * 4 + 3];

        }

 

        #endregion

 

        #region 픽셀 설정하기 - SetPixel(x, y, red, green, blue, alpha)

 

        /// <summary>

        /// 픽셀 설정하기

        /// </summary>

        /// <param name="x">X 좌표</param>

        /// <param name="y">Y 좌표</param>

        /// <param name="red">빨간색 채널</param>

        /// <param name="green">녹색 채널</param>

        /// <param name="blue">파란색 채널</param>

        /// <param name="alpha">알파 채널</param>

        public void SetPixel(int x, int y, byte red, byte green, byte blue, byte alpha)

        {

            int index = y * this.stride + x * 4;

 

            this.pixelArray[index++] = blue;

            this.pixelArray[index++] = green;

            this.pixelArray[index++] = red;

            this.pixelArray[index++] = alpha;

        }

 

        #endregion

 

        #region 파란색 채널 설정하기 - SetBlue(x, y, blue)

 

        /// <summary>

        /// 파란색 채널 설정하기

        /// </summary>

        /// <param name="x">X 좌표</param>

        /// <param name="y">Y 좌표</param>

        /// <param name="blue">파란색 채널</param>

        public void SetBlue(int x, int y, byte blue)

        {

            this.pixelArray[y * this.stride + x * 4] = blue;

        }

 

        #endregion

        #region 녹색 채널 설정하기 - SetGreen(x, y, blue)

 

        /// <summary>

        /// 녹색 채널 설정하기

        /// </summary>

        /// <param name="x">X 좌표</param>

        /// <param name="y">Y 좌표</param>

        /// <param name="blue">녹색 채널</param>

        public void SetGreen(int x, int y, byte green)

        {

            this.pixelArray[y * this.stride + x * 4 + 1] = green;

        }

 

        #endregion

        #region 빨간색 채널 설정하기 - SetRed(x, y, blue)

 

        /// <summary>

        /// 빨간색 채널 설정하기

        /// </summary>

        /// <param name="x">X 좌표</param>

        /// <param name="y">Y 좌표</param>

        /// <param name="blue">빨간색 채널</param>

        public void SetRed(int x, int y, byte red)

        {

            this.pixelArray[y * this.stride + x * 4 + 2] = red;

        }

 

        #endregion

        #region 알파 채널 설정하기 - SetAlpha(x, y, blue)

 

        /// <summary>

        /// 알파 채널 설정하기

        /// </summary>

        /// <param name="x">X 좌표</param>

        /// <param name="y">Y 좌표</param>

        /// <param name="blue">알파 채널</param>

        public void SetAlpha(int x, int y, byte alpha)

        {

            this.pixelArray[y * this.stride + x * 4 + 3] = alpha;

        }

 

        #endregion

 

        #region 색상 설정하기 - SetColor(red, green, blue, alpha)

 

        /// <summary>

        /// 색상 설정하기

        /// </summary>

        /// <param name="red">빨간색 채널</param>

        /// <param name="green">녹색 채널</param>

        /// <param name="blue">파란색 채널</param>

        /// <param name="alpha">알파 채널</param>

        public void SetColor(byte red, byte green, byte blue, byte alpha)

        {

            int byteCount = this.width * this.height * 4;

            int index     = 0;

 

            while(index < byteCount)

            {

                this.pixelArray[index++] = blue;

                this.pixelArray[index++] = green;

                this.pixelArray[index++] = red;

                this.pixelArray[index++] = alpha;

            }

        }

 

        #endregion

        #region 색상 설정하기 - SetColor(red, green, blue)

 

        /// <summary>

        /// 색상 설정하기

        /// </summary>

        /// <param name="red">빨간색 채널</param>

        /// <param name="green">녹색 채널</param>

        /// <param name="blue">파란색 채널</param>

        public void SetColor(byte red, byte green, byte blue)

        {

            SetColor(red, green, blue, 255);

        }

 

        #endregion

 

        #region 쓰기 가능 비트맵 구하기 - GetWriteableBitmap(dpiX, dpiY)

 

        /// <summary>

        /// 쓰기 가능 비트맵 구하기

        /// </summary>

        /// <param name="dpiX">DPU X</param>

        /// <param name="dpiY">DPU Y</param>

        /// <returns>쓰기 가능 비트맵</returns>

        public WriteableBitmap GetWriteableBitmap(double dpiX, double dpiY)

        {

            WriteableBitmap bitmap = new WriteableBitmap

            (

                this.width,

                this.height,

                dpiX,

                dpiY,

                PixelFormats.Bgra32,

                null

            );

 

            Int32Rect rectangle = new Int32Rect(0, 0, this.width, this.height);

 

            bitmap.WritePixels(rectangle, this.pixelArray, this.stride, 0);

 

            return bitmap;

        }

 

        #endregion

    }

}

 

 

MainWindow.xaml.cs

 

 

using System.Windows;

using System.Windows.Controls;

using System.Windows.Media;

using System.Windows.Media.Imaging;

 

namespace TestProject

{

    /// <summary>

    /// 메인 윈도우

    /// </summary>

    public partial class MainWindow : Window

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

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

 

        #region 생성자 - MainWindow()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainWindow()

        {

            InitializeComponent();

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        //////////////////////////////////////////////////////////////////////////////// Event

 

        #region 윈도우 로드시 처리하기 - Window_Loaded(sender, e)

 

        /// <summary>

        /// 윈도우 로드시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void Window_Loaded(object sender, RoutedEventArgs e)

        {

            const int WIDTH  = 240;

            const int HEIGHT = 240;

 

            BitmapHelper helper = new BitmapHelper(WIDTH, HEIGHT);

 

            helper.SetColor(0, 0, 0);

 

            for(int y = 0; y < 80; y++)

            {

                for(int x = 0; x <= y; x++)

                {

                    helper.SetBlue(x, y, 255);

                }

            }

 

            for(int x = 0; x < 80; x++)

            {

                for(int y = 80; y < 160; y++)

                {

                    helper.SetGreen(x, y, 255);

                }

            }

 

            for(int x = 0; x < 80; x++)

            {

                for(int y = 160; y < 240; y++)

                {

                    helper.SetRed(x, y, 255);

                }

            }

 

            for(int x = 80; x < 160; x++)

            {

                byte color = (byte)((x - 80f) / 80f * 255f);

 

                for(int y = 0; y < 80; y++)

                {

                    helper.SetBlue(x, y, color);

                }

 

                for(int y = 80; y < 160; y++)

                {

                    helper.SetGreen(x, y, color);

                }

 

                for(int y = 160; y < 240; y++)

                {

                    helper.SetRed(x, y, color);

                }

            }

 

            for(int x = 160; x < 240; x++)

            {

                for(int y = 0; y < 80; y++)

                {

                    helper.SetPixel(x, y, 255, 255, 0, 255);

                }

 

                for(int y = 80; y < 160; y++)

                {

                    helper.SetPixel(x, y, 0, 255, 255, 255);

                }

 

                for(int y = 160; y < 240; y++)

                {

                    helper.SetPixel(x, y, 255, 0, 255, 255);

                }

            }

 

            WriteableBitmap writeableBitmap = helper.GetWriteableBitmap(96, 96);

 

            Image image = new Image();

 

            image.Stretch = Stretch.None;

            image.Margin  = new Thickness(0);

 

            this.mainGrid.Children.Add(image);

 

            image.Source = writeableBitmap;

 

            writeableBitmap.Save("sample.bmp");

            writeableBitmap.Save("sample.gif");

            writeableBitmap.Save("sample.jpg");

            writeableBitmap.Save("sample.png");

            writeableBitmap.Save("sample.tif");

            writeableBitmap.Save("sample.wmp");

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker

댓글을 달아 주세요