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

728x90
반응형

■ Image 클래스 : LayoutUpdated 이벤트를 사용해 이미지 픽셀 보정하기

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


TestProject.zip


FixedImage.cs

 

 

using System;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Media;

 

namespace TestProject

{

    /// <summary>

    /// 고정 이미지

    /// </summary>

    public class FixedImage : Image

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

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

 

        #region 오프셋 포인트 - OffsetPoint

 

        /// <summary>

        /// 오프셋 포인트

        /// </summary>

        private Point OffsetPoint { get; set; }

 

        #endregion

 

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

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

 

        #region 생성자 - FixedImage()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public FixedImage()

        {

            LayoutUpdated += Image_LayoutUpdated;

        }

 

        #endregion

 

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

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

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

 

        #region 렌더링시 처리하기 - OnRender(drawingContext)

 

        /// <summary>

        /// 렌더링시 처리하기

        /// </summary>

        /// <param name="drawingContext">드로잉 컨텍스트</param>

        protected override void OnRender(DrawingContext drawingContext)

        {

            OffsetPoint = GetOffsetPoint();

 

            drawingContext.PushTransform(new TranslateTransform(OffsetPoint.X, OffsetPoint.Y));

 

            base.OnRender(drawingContext);

        }

 

        #endregion

 

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

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

 

        #region 이미지 레이아웃 업데이트시 처리하기 - Image_LayoutUpdated(sender, e)

 

        /// <summary>

        /// 이미지 레이아웃 업데이트시 처리하기

        /// </summary>

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

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

        private void Image_LayoutUpdated(object sender, EventArgs e)

        {

            Point currentOffsetPoint = GetOffsetPoint();

 

            double threshold = 0.001; // 1/100 픽셀

            double deltaX;

            double deltaY;

 

            deltaX = currentOffsetPoint.X - OffsetPoint.X;

            deltaY = currentOffsetPoint.Y - OffsetPoint.Y;

 

            if((((deltaX < threshold) && (deltaX > -threshold)) == false) || (((deltaY < threshold) && (deltaY > -threshold)) == false))

            {

                InvalidateVisual();

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////// Function

 

        #region 오프셋 포인트 구하기 - GetOffsetPoint()

 

        /// <summary>

        /// 오프셋 포인트 구하기

        /// </summary>

        /// <returns>오프셋 포인트</returns>

        private Point GetOffsetPoint()

        {

            Point offsetPoint = new Point();

 

            PresentationSource source = PresentationSource.FromVisual(this);

 

            if(source != null)

            {

                Visual rootVisual = source.RootVisual;

 

                offsetPoint = this.TransformToAncestor(rootVisual).Transform(new Point(0, 0));

 

                offsetPoint = source.CompositionTarget.TransformToDevice.Transform(offsetPoint);

 

                offsetPoint.X = Math.Round(offsetPoint.X);

                offsetPoint.Y = Math.Round(offsetPoint.Y);

 

                offsetPoint = source.CompositionTarget.TransformFromDevice.Transform(offsetPoint);

 

                offsetPoint = rootVisual.TransformToDescendant(this).Transform(offsetPoint);

            }

 

            return offsetPoint;

        }

 

        #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"

    xmlns:local="clr-namespace:TestProject"

    Width="800"

    Height="600"

    Title="Image 클래스 : LayoutUpdated 이벤트를 사용해 이미지 픽셀 보정하기"

    Background="Black"

    FontFamily="나눔고딕코딩"

    FontSize="16">

    <Grid Margin="10">

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="*" />

            <ColumnDefinition Width="10" />

            <ColumnDefinition Width="*" />

        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>

            <RowDefinition Height="*"    />

            <RowDefinition Height="10"   />

            <RowDefinition Height="Auto" />

        </Grid.RowDefinitions>

        <Border Grid.Row="0" Grid.Column="0"

            BorderThickness="1"

            BorderBrush="Black">

            <Image Name="image"

                Margin="0.5 0 0 0"

                Source="IMAGE/sample.png"

                Stretch="None" />

        </Border>

        <Border Grid.Row="0" Grid.Column="2"

            BorderThickness="1"

            BorderBrush="Black">

            <local:FixedImage x:Name="fixedImage"

                Margin="0.5 0 0 0"

                Source="IMAGE/sample.png"

                Stretch="None" />

        </Border>

        <Grid Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3">

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="*"    />

                <ColumnDefinition Width="10"   />

                <ColumnDefinition Width="Auto" />

            </Grid.ColumnDefinitions>

            <TextBox Name="textBox" Grid.Column="0"

                Height="25"

                Background="Transparent"

                BorderThickness="1"

                BorderBrush="Black" />

            <Button Name="openButton" Grid.Column="2"

                Width="100"

                Height="25"

                Content="이미지 열기" />

        </Grid>

    </Grid>

</Window>

 

 

MainWindow.xaml.cs

 

 

using Microsoft.Win32;

using System;

using System.Windows;

using System.Windows.Media.Imaging;

 

namespace TestProject

{

    /// <summary>

    /// 메인 윈도우

    /// </summary>

    public partial class MainWindow : Window

    {

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

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

 

        #region 생성자 - MainWindow()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainWindow()

        {

            InitializeComponent();

 

            this.openButton.Click += openButton_Click;

        }

 

        #endregion

 

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

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

 

        #region 이미지 열기 버튼 클릭시 처리하기 - openButton_Click(sender, e)

 

        /// <summary>

        /// 이미지 열기 버튼 클릭시 처리하기

        /// </summary>

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

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

        private void openButton_Click(object sender, RoutedEventArgs e)

        {

            OpenFileDialog openFileDialog = new OpenFileDialog();

 

            openFileDialog.Filter = "이미지 파일|*.jpg;*.gif;*.png";

 

            if(openFileDialog.ShowDialog() == true)

            {

                this.textBox.Text = openFileDialog.FileName;

 

                BitmapImage bitmapImage = new BitmapImage(new Uri(openFileDialog.FileName));

 

                this.image.Source = bitmapImage;

 

                this.fixedImage.Source = bitmapImage;

            }

        }

 

        #endregion

    }

}

 

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

728x90
반응형
Posted by 사용자 icodebroker
TAG , , , ,

댓글을 달아 주세요