Study/C#

C#에서 화면의 특정 부분 capture하기

13.d_dk 2021. 4. 8. 20:20
728x90
반응형

문제의 정의

 프로그램에서 화면 캡처(capture) 기능을 제공해야 할 때가 있다. 여기서 전체 화면에 대한 캡처가 아닌 부분 화면의 캡처가 필요한 경우도 있을 것이다. 이와 같이 부분 캡처를 수행하기 위한 C# 코드를 알아보자. 

 

방법

 이 방법을 수행하기 위한 코드는 Visual Studio 2012에서 수행되었다. C#에서 기본적으로 제공하는 네임스페이스(namespace) 중 System.Drawing과 System.Drawing.Imaging을 사용하여 특정 부분의 화면을 사각형을 캡처하고 이미지로 저장할 수 있다. 이 네임스페이스를 사용하기 위해 C# 프로젝트에서 참조를 먼저 추가해야 한다. 

 프로젝트를 생성하고 '참조'에 오른쪽 마우스 클릭을 하여 '참조 추가'를 선택하자. 

프로젝트에 참조 추가를 선택하기

 

 이후 '어셈블리-프레임워크'에서 System.Drawing을 찾아서 오른쪽의 체크 박스에 체크를 하자. 오른쪽 하단에 확인 버튼을 눌러 프로젝트의 참조에 선택한 네임스페이스를 추가하자.

어셈블리-프레임워크에서 System.Drawing 선택하기

 

 아래의 그림과 같이 참조에 System.Drawing이 추가된 것을 확인할 수 있다.

참조에 System.Drawing이 추가된 것을 확인

 

 이렇게 추가된 네임스페이스를 사용하기 위해 부분 화면 캡처 기능을 제공하는 C# 클래스를 정의하는 .cs 파일 상단에 네임스페이스를 정의해주자.

1
2
using System.Drawing;
using System.Drawing.Imaging;
cs

 

 부분 화면 캡처 기능을 제공하는 C# 클래스를 생성하자. 클래스의 이름은 ImgCapture이다. 이후 부분 화면 캡처의 기준이 되는 X, Y 좌표 값 변수들(int)와 이미지의 높이와 너비를 결정하는 변수들(int) 그리고 이미지를 저장할 경로 변수(string)를 생성하자.

1
2
3
4
5
6
7
8
9
public class ImgCapture
{
    private int _refX = 0;
    private int _refY = 0;
    private int _imgW = 0;
    private int _imgH = 0;
 
    private string filePath = null;
}
 
cs

 

 위의 화면의 기준 X(_refX), Y(_refY) 그리고 이미지의 높이(_imgH)와 너비(_imgW)를 통해 결정되는 캡처 영역은 아래의 그림과 같이 설명할 수 있다.

캡처될 이미지의 영역과 기준 X,Y 그리고 이미지 높이 및 너비의 관계

 

 이후 ImgCapture 클래스의 생성자를 정의하자. 생성자에 입력 파라미터로 4개의 int 값을 받도록 하자. 입력받은 4개의 int 값은 각각 부분 화면 캡처의 기준이 되는 X, Y 좌표 값과 이미지의 높이와 너비를 결정한다.

1
2
3
4
5
6
7
public ImgCapture(int refX = 0int refY = 0int imgW = 0int imgH = 0)
{
    _refX = refX;
    _refY = refY;
    _imgW = imgW;
    _imgH = imgH;
}
 
cs

 

 ImgCapture 클래스에 지역 변수인 이미지를 저장할 경로를 변경하는 함수를 만들자.

1
2
3
4
public void SetPath(string path)
{
    filePath = path;
}
 
cs

 

 마지막으로 정해진 입력 파라미터와 저장할 경로를 사용하여 부분 캡처를 수행하고 이미지 파일로 출력하여 저장하는 함수를 만들자. 여기서 Bitmap, Graphics는 System.Drawing namespace의 클래스이며 확장자와 관련된 ImageFormat는 System.Drawing.Imaging namespace의 클래스이다. 여기서 파일 경로가 지정되지 않거나, 이미지의 높이 및 너비가 0인 경우 이미지를 저장하지 않도록 설정하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void DoCaptureImage()
{
    if (filePath != null)
    {
        if (_imgW == 0 || _imgH == 0)
            return;
 
        using (System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap((int)_imgW, (int)_imgH))
        {
            using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap))
            {
                g.CopyFromScreen(_refX, _refY, 00, bitmap.Size);
            }
 
            bitmap.Save(filePath, ImageFormat.Png);
        }
    }
}
 
cs

 

 최종적으로 만들어진 클래스는 아래의 코드와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class ImgCapture
{
    private int _refX = 0;
    private int _refY = 0;
    private int _imgW = 0;
    private int _imgH = 0;
 
    private string filePath = null;
 
    public ImgCapture(int refX = 0int refY = 0int imgW = 0int imgH = 0)
    {
        _refX = refX;
        _refY = refY;
        _imgW = imgW;
        _imgH = imgH;
    }
 
    public void SetPath(string path)
    {
        filePath = path;
    }
 
    public void DoCaptureImage()
    {
        if (filePath != null)
        {
            if (_imgW == 0 || _imgH == 0)
                return;
 
            using (System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap((int)_imgW, (int)_imgH))
            {
                using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap))
                {
                    g.CopyFromScreen(_refX, _refY, 00, bitmap.Size);
                }
 
                bitmap.Save(filePath, ImageFormat.Png);
            }
        }
    }
}
 
cs

 

 이러한 클래스를 사용하여 테스트하는 코드는 아래와 같다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
class Program
{
    static void Main(string[] args)
    {
        string pngFilePath = "aaa.png";
 
        ImgCapture imgCapture = new ImgCapture(200200400400);
        imgCapture.SetPath(pngFilePath);
        imgCapture.DoCaptureImage();
 
        return;
    }
}
 
cs

 

Reference

 

Capture screenshot of active window?

I am making a screen capturing application and everything is going fine. All I need to do is capture the active window and take a screenshot of this active window. Does anyone know how I can do t...

stackoverflow.com

 

daegukdo/TIL

today I learned. Contribute to daegukdo/TIL development by creating an account on GitHub.

github.com

 

 

 

반응형