본문 바로가기

C#

[WPF] 멀티쓰레드 상황에서 WPF Control 캡처 하기

WPF 의 Shape 그리기나 , Shader Effect , Brushes 등등이 WPF 를 사용하면 아주 쉽고 처리속도에도 이점이 많다. 하지만 일반적인 방법으로는 메인쓰레드에서만 비주얼 요소를 사용할 수 있어 사용이 제한적이고 , 별도의 프로세싱을 위하여 사용 할 경우 CPU 사용량이 높아져 전체적인 GUI 가 버벅되는 현상이 발생 할 수도 있다.


이를 극복하기 위하여 멀티 쓰레드 상황에서 WPF 컨트롤에 접근 하는 방법을 알아 보자.



using System;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using WPF_Tilt;

namespace ThreadCaptureWPFTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Thread captureThread;
        public MainWindow()
        {
            InitializeComponent();


            //쓰레드 생성
            captureThread = new Thread(new ThreadStart(Ready));
            // STA 형태의 쓰레드 이여야 함
            captureThread.SetApartmentState(ApartmentState.STA); 
        }


        // 쓰레드
        private void Ready()
        {
            //ViewBox, Grid , Canvas 등.. 생성
            Grid vb = new Grid();

            //XAML 로 만든 UserControl 도 가능함.
            vb.Children.Add(new View());
            vb.Arrange(new Rect(0, 0, 500, 500)); //중요!

            //RenderTargetBitmap 생성
            RenderTargetBitmap capture = new RenderTargetBitmap((int)vb.ActualWidth, (int)vb.ActualHeight, 96, 96, PixelFormats.Default);
            capture.Render(vb);

            var bmp = BitmapConvertUtil.ToBitmap(capture);
            bmp.Save(@"TestCap1.jpg");
            Console.WriteLine("CAP!"); 
        }



        private void root_KeyUp_1(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.A)
            {
                captureThread.Start();
            }
        }
    }
}