[C#] 스포이드 프로그램(color hex-data 추출기)


Development note/C#  2021. 1. 21. 16:25

안녕하세요. 명월입니다.


이 글은 C#을 이용해서 만든 스포이드 프로그램(color hex-data 추출기)에 대한 글입니다.


사실 이 글은 예전에 작성해서 게시했습니다만, 내용도 오래되었고 해서 다시 작성했습니다.

이전 글에서 전역 마우스 이벤트를 사용하는 방법에 대해 설명한 적 있습니다.

link - [C#] 키보드와 마우스의 전역 이벤트를 사용하는 법(키보드와 마우스 후킹)


그 것을 이용하는 것이기는 한데, 마우스 포인터가 가르키는 모니터 상의 색을 추출하는 프로그램입니다.

아마 프로그램 개발하는 데 많은 도움이 될 수 있는 도구 프로그램이기도 합니다.

스크린 샷으로는 마우스 포인터가 캡쳐가 되지 않아서 정확한 사용하는 모습이 이미지로 표현이 되지 않습니다만, 마우스 포인터가 가르키는 곳이 RGB형태와 RGB의 HEX 데이터 형식으로 표현이 됩니다.

첨부 - spoid.zip


그냥 사용하실 분들은 위의 zip 파일을 다운 받으셔서 압축을 푸신 후 실행하시면 됩니다.


그럼 스포이드 프로그램을 만들기 위해서 먼저 전역 이벤트를 사용할 라이브러리를 nuget으로 추가합니다.

using System;
using System.Drawing;
using System.Windows.Forms;
using Gma.System.MouseKeyHook;
using System.Text;

namespace Spoid
{
  //확장 클래스
  public static class ExtendControl
  {
    // 동기화 함수 추가
    public static void InvokeControl(this Control ctl, Action func)
    {
      // 메시지가 실행 중이면
      if (ctl.InvokeRequired)
      {
        // Invoke 함수로 동기화 한다.
        ctl.Invoke(func);
      }
      else
      {
        // 그냥 함수 호출
        func();
      }
    }
    // 동기화 함수 추가 (Return이 가능하다.)
    public static T InvokeControl<T>(this Control ctl, Func<T> func)
    {
      // 메시지가 실행 중이면
      if (ctl.InvokeRequired)
      {
        // Invoke 함수로 동기화 한다.
        return (T)ctl.Invoke(func);
      }
      else
      {
        // 그냥 함수 호출
        return func();
      }
    }
  }
  // 윈도우 폼을 상속한다.
  class Program : Form
  {
    // 라벨을 생성한다.
    private Label label1 = new Label()
    {
      AutoSize = true,
      Location = new Point(12, 9),
      Size = new Size(38, 12),
      TabIndex = 0
    };
    // 색을 표시할 파넬을 생성한다.
    private Panel panel1 = new Panel()
    {
      Location = new Point(111, 9),
      Size = new Size(47, 45),
      TabIndex = 1
    };
    // 임시 버퍼
    private Bitmap buffer = new Bitmap(1, 1);
    // 임시 버퍼의 graphic 타입
    private Graphics buffer_graphics = null;
    // 텍스트 버퍼
    private StringBuilder sb = new StringBuilder();
    // 생성자
    public Program()
    {
      // 임시 버퍼로 graphic 타입을 가져온다.
      this.buffer_graphics = Graphics.FromImage(buffer);
      // 폼을 설정한다.
      InitDesign();
    }
    // 폼 디자인 설정
    private void InitDesign()
    {
      this.SuspendLayout();
      // 컨트롤 추가
      this.Controls.Add(this.panel1);
      this.Controls.Add(this.label1);
      this.ResumeLayout(false);

      this.AutoScaleDimensions = new SizeF(7F, 12F);
      this.AutoScaleMode = AutoScaleMode.Font;
      // 폼 이름 설정
      this.Text = "Spoid";
      // 폼 스타일 설정
      this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
      // 폼 크기 설정
      this.MaximumSize = this.MinimumSize = new Size(170, 175);
      this.PerformLayout();
      // 현재 포인트로 초기 설정
      SetView(MousePosition.X, MousePosition.Y);
      // 키보트 키 전역 이벤트
      Hook.GlobalEvents().KeyDown += (s, e) =>
      {
        // Control + C를 누르면
        if (e.Control && e.KeyCode == Keys.C)
        {
          // 현재의 색을 클립 보드에 저장
          SetView(MousePosition.X, MousePosition.Y, true);
        }
      };
      // 마우스 이동 전역 이벤트
      Hook.GlobalEvents().MouseMove += (s, e) =>
      {
        // 현재 색을 폼에 설정
        SetView(e.X, e.Y);
      };
    }
    // 폼 설정
    private void SetView(int x, int y, bool capture = false)
    {
      // 텍스트 버퍼 초기화
      sb.Clear();
      // 마우스 좌표를 표시한다.
      sb.AppendLine($"X point : {x}");
      sb.AppendLine($"Y point : {y}");
      // 포인터가 가르키는 곳의 색을 취득한다.
      var color = ScreenColor(x, y);
      // RGB색을 라벨에 표시한다.
      sb.AppendLine($"R : {color.R}");
      sb.AppendLine($"G : {color.G}");
      sb.AppendLine($"B : {color.B}");
      // RGB를 HEX 표기법으로 표시한다.
      sb.Append("Code : ");
      sb.Append(ToHexString(color.R).Substring(0, 2));
      sb.Append(ToHexString(color.G).Substring(0, 2));
      sb.Append(ToHexString(color.B).Substring(0, 2));
      // Control + C의 경우는 클립보드에 저장한다.
      if (capture)
      {
        Clipboard.SetText(sb.ToString());
      }
      // 개행
      sb.AppendLine();
      sb.AppendLine();
      // 사용법을 표시한다.
      sb.AppendLine("If press the Ctrl + C,");
      sb.AppendLine("    to copy to clipboard. ");
      // 텍스트 버퍼의 글을 폼의 라벨에 표시힌다.
      this.label1.InvokeControl(() =>
      {
        this.label1.Text = sb.ToString();
        // 텍스트 버처 초기화
        sb.Clear();
      });
      // 현재 색을
      this.panel1.InvokeControl(() =>
      {
        // 파넬에 표시한다.
        this.panel1.BackColor = color;
      });
    }
    // 색깔 추출하기
    private Color ScreenColor(int x, int y)
    {
      // Mouse 위치의 색을 추출한다.
      this.buffer_graphics.CopyFromScreen(x, y, 0, 0, new Size(1, 1));
      // Pixel 값을 리턴한다.
      return this.buffer.GetPixel(0, 0);
    }
    // 10진수를 16진수로 표현
    public string ToHexString(int nor)
    {
      // byte형식으로 표현
      byte[] bytes = BitConverter.GetBytes(nor);
      // 이것을 16진수로 표현
      string hexString = "";
      for (int i = 0; i < bytes.Length; i++)
      {
        hexString += bytes[i].ToString("X2");
      }
      // String 타입으로 리턴
      return hexString;
    }
    [STAThread]
    // 실행 함수
    static void Main(string[] args)
    {
      // 환경에 맞는 스타일 설정
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      // 메시지 루프에 인스턴스를 생성한다.
      Application.Run(new Program());
    }
  }
}

마우스를 움직이면 포인터가 있는 위치의 색을 가져와서 RGB와 Hex 데이터를 윈도우 폼에 표시되는 것을 확인할 수 있습니다.

그 상태에서 Ctrl + C를 누르면 데이터가 클립보드에 저장이 되고 메모장에서 Ctrl + V를 누르면 데이터 복사가 제대로 되는 것을 확인할 수 있습니다.


여기까지 C#을 이용해서 만든 스포이드 프로그램(color hex-data 추출기)에 대한 글이었습니다.


궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.