첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

■ RenderTargetBitmap 클래스 : 텍스트 그리기

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


TestProject.zip


VerticalAlignment.cs

 

 

namespace TestProject

{

    /// <summary>

    /// 수직 정렬

    /// </summary>

    public enum VerticalAlignment

    {

        /// <summary>

        /// 상단

        /// </summary>

        Top,

 

        /// <summary>

        /// 중단

        /// </summary>

        Middle,

 

        /// <summary>

        /// 하단

        /// </summary>

        Bottom,

    }

}

 

 

DrawingContextExtension.cs

 

 

using System.Globalization;

using System.Linq;

using System.Windows;

using System.Windows.Media;

using System.Windows.Media.Imaging;

 

namespace TestProject

{

    /// <summary>

    /// 그리기 컨텍스트 확장

    /// </summary>

    public static class DrawingContextExtension

    {

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

        ////////////////////////////////////////////////////////////////////////////////////////// Static

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

 

        #region 문자열 그리기 - DrawString(drawingContext, text, fontName, emSize, brush, originPoint, verticalAlignment,

            horizontalAlignment)

 

        /// <summary>

        /// 문자열 그리기

        /// </summary>

        /// <param name="drawingContext">그리기 컨텍스트</param>

        /// <param name="text">텍스트</param>

        /// <param name="fontName">폰트명</param>

        /// <param name="emSize">EM 크기</param>

        /// <param name="brush">브러시</param>

        /// <param name="originPoint">원점 포인트</param>

        /// <param name="verticalAlignment">수직 정렬</param>

        /// <param name="horizontalAlignment">수평 정렬</param>

        public static void DrawString(this DrawingContext drawingContext, string text, string fontName, double emSize, Brush brush,

            Point originPoint, VerticalAlignment verticalAlignment, TextAlignment horizontalAlignment)

        {

            Typeface typeface = new Typeface(fontName);

 

            FormattedText formattedText = new FormattedText

            (

                text,

                CultureInfo.CurrentUICulture,

                FlowDirection.LeftToRight,

                typeface,

                emSize,

                brush

            );

 

            formattedText.TextAlignment = horizontalAlignment;

 

            if(verticalAlignment == VerticalAlignment.Middle)

            {

                originPoint.Y -= formattedText.Height / 2;

            }

            else if(verticalAlignment == VerticalAlignment.Bottom)

            {

                originPoint.Y -= formattedText.Height;

            }

 

            drawingContext.DrawText(formattedText, originPoint);

        }

 

        #endregion

        #region 문자열 그리기 - DrawString(drawingContext, text, rotateAngle, fontName, emSize, brush, originPoint, textAlignment,

            verticalAlignment, horizontalAlignment)

 

        /// <summary>

        /// 문자열 그리기

        /// </summary>

        /// <param name="drawingContext">그리기 컨텍스트</param>

        /// <param name="text">텍스트</param>

        /// <param name="rotateAngle">회전 각도</param>

        /// <param name="fontName">폰트명</param>

        /// <param name="emSize">EM 크기</param>

        /// <param name="brush">브러시</param>

        /// <param name="originPoint">원점 포인트</param>

        /// <param name="textAlignment">텍스트 정렬</param>

        /// <param name="verticalAlignment">수직 정렬</param>

        /// <param name="horizontalAlignment">수평 정렬</param>

        public static void DrawString(this DrawingContext drawingContext, string text, double rotateAngle, string fontName,

            double emSize, Brush brush, Point originPoint, TextAlignment textAlignment, VerticalAlignment verticalAlignment,

            TextAlignment horizontalAlignment)

        {

            Typeface typeface = new Typeface(fontName);

 

            FormattedText formattedText = new FormattedText

            (

                text,

                CultureInfo.CurrentUICulture,

                FlowDirection.LeftToRight,

                typeface,

                emSize,

                brush

            );

 

            formattedText.TextAlignment = textAlignment;

 

            double width  = formattedText.Width - formattedText.OverhangLeading;

            double height = formattedText.Height;

 

            TranslateTransform translateTransform1 = new TranslateTransform();

 

            translateTransform1.Y = -height / 2;

 

            if((textAlignment == TextAlignment.Left) || (textAlignment == TextAlignment.Justify))

            {

                translateTransform1.X = -width / 2;

            }

            else if(textAlignment == TextAlignment.Right)

            {

                translateTransform1.X = width / 2;

            }

            else

            {

                translateTransform1.X = 0;

            }

 

            RotateTransform rotateTransform = new RotateTransform(rotateAngle);

 

            Rect rectangle = new Rect(0, 0, width, height);

 

            if(textAlignment == TextAlignment.Center)

            {

                rectangle.X -= width / 2;

            }

            else if(textAlignment == TextAlignment.Right)

            {

                rectangle.X -= width;

            }

 

            Rect rotateRectangle = rotateTransform.TransformBounds(rectangle);

 

            TranslateTransform translateTransform2 = new TranslateTransform(originPoint.X, originPoint.Y);

 

            if(horizontalAlignment == TextAlignment.Left)

            {

                translateTransform2.X += rotateRectangle.Width / 2;

            }

            else if(horizontalAlignment == TextAlignment.Right)

            {

                translateTransform2.X -= rotateRectangle.Width / 2;

            }

 

            if(verticalAlignment == VerticalAlignment.Top)

            {

                translateTransform2.Y += rotateRectangle.Height / 2;

            }

            else if(verticalAlignment == VerticalAlignment.Bottom)

            {

                translateTransform2.Y -= rotateRectangle.Height / 2;

            }

 

            drawingContext.PushTransform(translateTransform2);

            drawingContext.PushTransform(rotateTransform);

            drawingContext.PushTransform(translateTransform1);

 

            drawingContext.DrawText(formattedText, new Point(0, 0));

 

            drawingContext.DrawRectangle(null, new Pen(Brushes.Red, 1), rectangle);

 

            drawingContext.Pop();

            drawingContext.Pop();

            drawingContext.Pop();

 

            Rect transformRectangle = translateTransform2.TransformBounds

            (

                rotateTransform.TransformBounds

                (

                    translateTransform1.TransformBounds(rectangle)

                )

            );

 

            Pen customPen = new Pen(Brushes.Blue, 1);

 

            customPen.DashStyle = new DashStyle(new double[] { 5, 5 }, 0);

 

            drawingContext.DrawRectangle(null, customPen, transformRectangle);

        }

 

        #endregion

        #region 다각형 그리기 - DrawPolygon(drawingContext, brush, pen, pointArray, fillRule)

 

        /// <summary>

        /// 다각형 그리기

        /// </summary>

        /// <param name="drawingContext">그리기 컨텍스트</param>

        /// <param name="brush">브러시</param>

        /// <param name="pen"></param>

        /// <param name="pointArray">포인트 배열</param>

        /// <param name="fillRule">채우기 규칙</param>

        public static void DrawPolygon(this DrawingContext drawingContext, Brush brush, Pen pen, Point[] pointArray, FillRule fillRule)

        {

            drawingContext.DrawPolygonOrPolyline(brush, pen, pointArray, fillRule, true);

        }

 

        #endregion

        #region 다각선 그리기 - DrawPolyline(drawingContext, brush, pen, pointArray, fillRule)

 

        /// <summary>

        /// 다각선 그리기

        /// </summary>

        /// <param name="drawingContext">그리기 컨텍스트</param>

        /// <param name="brush">브러시</param>

        /// <param name="pen"></param>

        /// <param name="pointArray">포인트 배열</param>

        /// <param name="fillRule">채우기 규칙</param>

        public static void DrawPolyline(this DrawingContext drawingContext, Brush brush, Pen pen, Point[] pointArray, FillRule fillRule)

        {

            drawingContext.DrawPolygonOrPolyline(brush, pen, pointArray, fillRule, false);

        }

 

        #endregion

        #region 렌더 타겟 비트맵 구하기 - GetRenderTargetBitmap(text, dpiX, dpiY, fontName, emSize, textAlignment, backgroundBrush,

            rectanglePen, textBrush, margin)

 

        /// <summary>

        /// 렌더 타겟 비트맵 구하기

        /// </summary>

        /// <param name="text">텍스트</param>

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

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

        /// <param name="fontName">폰트명</param>

        /// <param name="emSize">EM 크기</param>

        /// <param name="textAlignment">텍스트 정렬</param>

        /// <param name="backgroundBrush">배경 브러시</param>

        /// <param name="rectanglePen">사각형 펜</param>

        /// <param name="textBrush">텍스트 브러시</param>

        /// <param name="margin">마진</param>

        /// <returns>렌더 타겟 비트맵</returns>

        public static RenderTargetBitmap GetRenderTargetBitmap(string text, double dpiX, double dpiY, string fontName, double emSize,

            TextAlignment textAlignment, Brush backgroundBrush, Pen rectanglePen, Brush textBrush, Thickness margin)

        {

            Typeface typeface = new Typeface(fontName);

 

            FormattedText formattedText = new FormattedText

            (

                text,

                CultureInfo.CurrentUICulture,

                FlowDirection.LeftToRight,

                typeface,

                emSize,

                textBrush

            );

 

            formattedText.TextAlignment = textAlignment;

 

            double width  = formattedText.Width - formattedText.OverhangLeading;

            double height = formattedText.Height;

 

            Point textOriginPoint = new Point(0, 0);

 

            if(textAlignment == TextAlignment.Center)

            {

                textOriginPoint.X = width / 2;

            }

            else if(textAlignment == TextAlignment.Right)

            {

                textOriginPoint.X = width;

            }

 

            if(rectanglePen != null)

            {

                width  += rectanglePen.Thickness;

                height += rectanglePen.Thickness;

 

                textOriginPoint.X += rectanglePen.Thickness / 2;

                textOriginPoint.Y += rectanglePen.Thickness / 2;

            }

 

            width  += margin.Left + margin.Right;

            height += margin.Top  + margin.Bottom;

 

            textOriginPoint.X += margin.Left;

            textOriginPoint.Y += margin.Top;

 

            int widthInteger  = (int)(width + 1);

            int heightInteger = (int)(height + 1);

 

            DrawingVisual  drawingVisual  = new DrawingVisual();

            DrawingContext drawingContext = drawingVisual.RenderOpen();

 

            drawingContext.DrawRectangle(backgroundBrush, rectanglePen, new Rect(0, 0, widthInteger, heightInteger));

 

            drawingContext.DrawText(formattedText, textOriginPoint);

 

            drawingContext.Close();

 

            RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap

            (

                widthInteger,

                heightInteger,

                dpiX,

                dpiY,

                PixelFormats.Pbgra32

            );

 

            renderTargetBitmap.Render(drawingVisual);

 

            return renderTargetBitmap;

        }

 

        #endregion

 

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

 

        #region 다각형 또는 다각선 그리기 - DrawPolygonOrPolyline(drawingContext, brush, pen, pointArray, fillRule, drawPolygon)

 

        /// <summary>

        /// 다각형 또는 다각선 그리기

        /// </summary>

        /// <param name="drawingContext">그리기 컨텍스트</param>

        /// <param name="brush">브러시</param>

        /// <param name="pen"></param>

        /// <param name="pointArray">포인트 배열</param>

        /// <param name="fillRule">채우기 규칙</param>

        /// <param name="drawPolygon">다각형 그리기 여부</param>

        private static void DrawPolygonOrPolyline(this DrawingContext drawingContext, Brush brush, Pen pen, Point[] pointArray,

            FillRule fillRule, bool drawPolygon)

        {

            StreamGeometry streamGeometry = new StreamGeometry();

 

            streamGeometry.FillRule = fillRule;

 

            using(StreamGeometryContext context = streamGeometry.Open())

            {

                context.BeginFigure(pointArray[0], true, drawPolygon);

 

                context.PolyLineTo(pointArray.Skip(1).ToArray(), true, false);

            }

 

            drawingContext.DrawGeometry(brush, pen, streamGeometry);

        }

 

        #endregion

    }

}

 

 

MainWindow.xaml

 

 

<Window x:Class="TestProject.MainWindow"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Width="800"

    Height="600"

    Title="RenderTargetBitmap 클래스 : 텍스트 그리기"

    Loaded="Window_Loaded">

    <Grid>

        <WrapPanel>

            <WrapPanel.Resources>

                <Style TargetType="Image">

                    <Setter Property="Stretch" Value="None" />

                    <Setter Property="Margin" Value="4" />

                </Style>

            </WrapPanel.Resources>

            <Image Name="img1"/>

            <Image Name="img2"/>

            <Image Name="img3"/>

            <Image Name="img4"/>

            <Image Name="img5"/>

            <Image Name="img6"/>

        </WrapPanel>

    </Grid>

</Window>

 

 

MainWindow.xaml.cs

 

 

using System.Windows;

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

 

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

 

        /// <summary>

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

        /// </summary>

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

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

        private void Window_Loaded(object sender, RoutedEventArgs e)

        {

            const string FONT_NAME = "Times New Roman";

            const double EM_SIZE   = 40;

 

            LinearGradientBrush brush = new LinearGradientBrush();

 

            brush.GradientStops.Add(new GradientStop(Colors.Red   , 0.0      ));

            brush.GradientStops.Add(new GradientStop(Colors.Orange, 1.0 / 6.0));

            brush.GradientStops.Add(new GradientStop(Colors.Yellow, 2.0 / 6.0));

            brush.GradientStops.Add(new GradientStop(Colors.Lime  , 3.0 / 6.0));

            brush.GradientStops.Add(new GradientStop(Colors.Blue  , 4.0 / 6.0));

            brush.GradientStops.Add(new GradientStop(Colors.Indigo, 5.0 / 6.0));

            brush.GradientStops.Add(new GradientStop(Colors.Violet, 1.0      ));

 

            Pen rectanglePen = new Pen(brush, 20);

 

            Brush backgroundBrush = new SolidColorBrush(Color.FromArgb(255, 240, 240, 240));

 

            RenderTargetBitmap bitmap1 = DrawingContextExtension.GetRenderTargetBitmap

            (

                "Left\nJustified",

                96,

                96,

                FONT_NAME,

                EM_SIZE,

                TextAlignment.Left,

                backgroundBrush,

                rectanglePen,

                brush,

                new Thickness(0)

            );

 

            image1.Source = bitmap1;

 

            RenderTargetBitmap bitmap2 = DrawingContextExtension.GetRenderTargetBitmap

            (

                "Center\nJustified",

                96,

                96,

                FONT_NAME,

                EM_SIZE,

                TextAlignment.Center,

                backgroundBrush,

                rectanglePen,

                brush,

                new Thickness(0)

            );

 

            image2.Source = bitmap2;

 

            RenderTargetBitmap bitmap3 = DrawingContextExtension.GetRenderTargetBitmap

            (

                "Right\nJustified",

                96,

                96,

                FONT_NAME,

                EM_SIZE,

                TextAlignment.Right,

                backgroundBrush,

                rectanglePen,

                brush,

                new Thickness(0)

            );

 

            image3.Source = bitmap3;

 

            RenderTargetBitmap bitmap4 = DrawingContextExtension.GetRenderTargetBitmap

            (

                "Margin\n(20)",

                96,

                96,

                FONT_NAME,

                EM_SIZE,

                TextAlignment.Center,

                backgroundBrush,

                rectanglePen,

                brush,

                new Thickness(20)

            );

 

            image4.Source = bitmap4;

 

            RenderTargetBitmap bitmap5 = DrawingContextExtension.GetRenderTargetBitmap

            (

                "Margin\n(20,0,0,20)",

                96,

                96,

                FONT_NAME,

                EM_SIZE,

                TextAlignment.Center,

                backgroundBrush,

                rectanglePen,

                brush,

                new Thickness(20, 0, 0, 20)

            );

 

            image5.Source = bitmap5;

 

            RenderTargetBitmap bitmap6 = DrawingContextExtension.GetRenderTargetBitmap

            (

                "Margin\n(0,20,20,0)",

                96,

                96,

                FONT_NAME,

                EM_SIZE,

                TextAlignment.Center,

                backgroundBrush,

                rectanglePen,

                brush,

                new Thickness(0, 20, 20, 0)

            );

 

            image6.Source = bitmap6;            

        }

 

        #endregion

    }

}

 

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

Posted by 사용자 icodebroker

댓글을 달아 주세요