C#/WPF

[C# - WPF] Bitmap위에 도형 그리는 방법 두가지

반나무 2022. 6. 16. 19:41

안녕하세요, 반나무입니다.

Bitmap위에 도형을 그리는 방법 두가지를 열심히 찾아서 소개합니다.

 

1. BitmapImage를 출력하고 ZIndex로 위에 BitmapSource로 도형을 그린 이미지를 올린다.
2. Bitmap에 Graphics로 도형을 그려 출력한다. 

 

우선 기본적인 바인딩은 다 적용했다는 가정하에 시작하겠습니다.

저는 일반적인 바인딩 방법을 사용했습니다.

 

1. ZIndex방법

<Grid>
    <Image Source="{Binding SourceImage}" Panel.ZIndex="10"/>
    <Image Source="{Binding DisplayImage}"/>
</Grid>

MainWindow.xaml

 

using System.Windows.Media.Imaging;
using System.Windows.Media;


// 로컬 이미지 가져오기 
MyBitmap = new Bitmap("D://hello.bmp");

// 이미지 사이즈로 도형을 새로 그린다.
RenderTargetBitmap rtb = new RenderTargetBitmap(MyBitmap.Width, MyBitmap.Height, 96d, 96d, PixelFormats.Pbgra32);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
	// 투명한 Background의 도형이미지 그리기
    dc.DrawRoundedRectangle(System.Windows.Media.Brushes.Transparent, new System.Windows.Media.Pen(System.Windows.Media.Brushes.Red,10), new System.Windows.Rect(100, 100, 100, 100), 0, 0);
    dc.Close();
    rtb.Render(dv);
    if (rtb.IsFrozen)
        rtb.Freeze();
}

// 도형 이미지 바인딩 출력
SourceImage = rtb;

// 이미지 바인딩 출력
DisplayImage = BitmapToBitmapImage(MyBitmap.Clone() as Bitmap);

MainViewModel.cs

좌 : 원본이미지 / 우 : 네모가 그려진 이미지

여기서 Bitmap의 가로,세로 크기는 장치독립적인 값으로 96 dpi로 계산된값임 만약 dpi를 변경한다면 가로,세로 크기도 동일하게 변경해줘야 한다.

bitmap의 가로크기 = bitmap 가로픽셀 수 x dpi X / 96
bitmap의 세로크기 = bitmap 세로픽셀 수 x dpi Y / 96

 

2. 이미지 합성

using System.Windows.Media;

// 로컬 이미지 가져오기 
MyBitmap = new Bitmap("D://hello.bmp");
            
// Bitmap 생성
Bitmap bitmap = new Bitmap(MyBitmap.Width, MyBitmap.Height);

// 펜 생성
System.Drawing.Pen redPen = new System.Drawing.Pen(System.Drawing.Brushes.Red, 10);
using (Graphics g = Graphics.FromImage(bitmap))
{
    // 이미지 그리기
    g.DrawImage(MyBitmap, 0, 0, MyBitmap.Width, MyBitmap.Height);
    // 도형 그리기 - X,Y좌표입력 후 100x100 사각형을 그림
    g.DrawRectangle(redPen, new Rectangle(MyBitmap.Width / 2, MyBitmap.Height / 2, 100, 100));
}
// 바인딩
DisplayImage = BitmapToBitmapImage(bitmap.Clone() as Bitmap);

// Dispose
redPen.Dispose();
bitmap.Dispose();

MainViewModel.cs

이미지 합성방법은 정말 중요한 문제가있다!!
이미지를 먼저 그린다음 그림을 그려야한다
그렇지않으면 그림을 그린다음 이미지가 그려져 그림이 묻히게된다.

좌 : 원본이미지 / 우 : 합성이미지(X,Y 센터, 100x100의 사각형)

 

반응형