첨부 소스 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

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
    }
}

 

728x90

 

▶ 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>

 

300x250

 

▶ 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

댓글을 달아 주세요