FontAwesome.Sharp

Winform 개발시 프로그램과 상호작용 하는 Button 컨트롤은 필수적으로 사용하게 되는데

기본 Button 컨트롤에도 이미지를 넣을 수 있지만 버튼 크기에 맞추어 일일이 이미지 파일을 구해서 추가하는 것도 시간을 꽤나 잡아먹는데 해당 Package의 Button을 사용하면 빠르게 아이콘 버튼을 구현 할 수 있어 생산성을 높일 수 있다.

WinForms 및 WPF 애플리케이션에서 FontAwesome 아이콘을 사용할 수 있도록 해주는 라이브러리이다.
(아파치 라이선스 2.0) 
FontAwesome.Sharp.Pro와 FontAwesome.Sharp.Material의 차이점은 FontAwesome.Shape는 두 패키지를 모두를 가지고 있음과 동시에 해당 Nuget 패키지를 사용하는데 필요한 의존성이라는 점이다. 
Pro: 1500개 이상의 아이콘 사용 가능 (유료)
Material: 900개 이상의 아이콘 사용 가능 (조건적 무료)
  • FontAwesome.Sharp.Pro: Font Awesome Pro License 상업적으로 사용시 Font Awesome 웹사이트에서 라이선스를 구매가 필요하다.
  • FontAwesome.Sharp.Material: Font Awesome Free License 상업적으로 사용시 별도의 라이선스 구매 필요없이 FontAwesome.com 웹사이트에 링크만 추가하면 사용이 가능하다.

ETC .net 6.0 .net framework 4.8 동일

Nuget 패키지 관리를 통해 해당 패키지를 설치하고 도구 상자를 이용해 사용하면 되는 점은 같으나
만약 실행 시 Program.cs 파일에서 new FontAwesome.Sharp가 인식이 안되어 사용이 불가능하다면 
Font Awesome.Sharp Package 들을 삭제하고 다시 설치 후
using FontAwesome.Sharp;를 Form 파일의 제일 위에 추가한 다음 실행하면 어느 정도 해결된다.

using HalconDotNet;
using OpenCvSharp;
using OpenCvSharp.Extensions;

static HObject MatToHObject(Mat mat)
        {
            HObject hObject;
            int width = mat.Width;
            int height = mat.Height;
            int channels = mat.Channels();

            if (channels == 1)
            {
                HOperatorSet.GenImage1(out hObject, "byte", width, height, mat.Data);
            }
            else if (channels == 3)
            {
                Mat[] splitChannels = mat.Split();
                HObject hRed, hGreen, hBlue;
                HOperatorSet.GenImage1(out hRed, "byte", width, height, splitChannels[2].Data);
                HOperatorSet.GenImage1(out hGreen, "byte", width, height, splitChannels[1].Data);
                HOperatorSet.GenImage1(out hBlue, "byte", width, height, splitChannels[0].Data);
                HOperatorSet.Compose3(hRed, hGreen, hBlue, out hObject);
            }
            else
            {
                throw new NotSupportedException("Unsupported number of channels in Mat");
            }

            return hObject;
        }

OpenCV (Open Source Computer Vision Library)

  • 오픈 소스 컴퓨터 비전 라이브러리로, 실시간 이미지 처리와 컴퓨터 비전 애플리케이션 개발에 사용되는 프로그래밍 함수들의 모음
  • 주요기능
    • 이미지 처리
    • 특징 검출 및 기술자 추출
    • 객체 인식 및 추적
    • 카메라 캘리브레이션 및 3D 복원
    • 기계 학습
    • 옵티컬 플로우와 모션 분석

C# 에서의 활용 목적

  • 이미지 처리 과정을 손쉽게 하기 위해서

실습 (저장된 사진을 불러와 Gray로 바꾸고 PictureBox에 로드하기)

1. 프로젝트 생성

2. PictureBox, Button 컨트롤 가져다 두기

3. OpenCV 라이브러리 다운 (프로젝트 -> NuGet패키지 관리 -> 찾아보기 OpenCVSharp 검색)

(설치)

OpenCvSharp4,

OpenCvSharp4.Extensions (타입 변환등 OpenCvSharp4 라이브러리를 활용하는 작업을 쉽게 할 수 있도록 도와주는 각종 메서드가 사용가능해진다.)

4. 코드 작성

using OpenCvSharp;
using OpenCvSharp.Extensions;

namespace OpenCVTest2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog dig = new OpenFileDialog();
                if(dig.ShowDialog() == DialogResult.OK)
                {
                    // 해당 경로에서 이미지를 가지고와 Mat타입으로 변환
                    Mat image = Cv2.ImRead(dig.FileName);
                    Mat grayImage = new Mat();
                    Cv2.CvtColor(image, grayImage, ColorConversionCodes.BGR2GRAY);
					
                    // grayImage 위에 텍스트 쓰기
                    string text = "Hello, OpenCvSharp!";
                    OpenCvSharp.Point textPosition = new OpenCvSharp.Point(10, 50); // 이미지 상의 텍스트 위치
                    HersheyFonts font = HersheyFonts.HersheySimplex; // 폰트 선택
                    double fontSize = 1.0; // 폰트 크기
                    Scalar textColor = new Scalar(0, 255, 0); // 색상(Green)
                    int textThickness = 2; // 텍스트 두께
                    Cv2.PutText(grayImage, text, textPosition, font, fontSize, textColor, textThickness);

                    
                    // OpenCvSharp.Extensions의 메소드 ToBitMap()을 통해 Mat타입을 Bitmap 타입으로 변경
                    pictureBox.Image = grayImage.ToBitmap();
                }
            }catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}

4-1. 이때 해당 오류가 발생하는데 아래 사이트에 접속 후 다음 과정을 진행해 주어야 오류를 해결 할 수 있다.

도움받은 블로그: https://luckygg.tistory.com/331 

https://github.com/shimat/opencvsharp

 

GitHub - shimat/opencvsharp: OpenCV wrapper for .NET

OpenCV wrapper for .NET. Contribute to shimat/opencvsharp development by creating an account on GitHub.

github.com

다운 받은 버전과 가급적 같은 버전을 선택하고 다운 후 압축풀기

여기서 NativeLib 폴더 > win 폴더 > x86 또는 x64의 OpenCvSharpExtern.dll 파일을 복사합니다.

그 후 해당 프로젝트 내에 파일을 복사 붙여넣고 

5. 결과 확인

        private Button currentButton;
        
        private void ButtonClick(object sender, EventArgs e)
        {
            ActiveButton(sender);
        }
        
        private void DisableButton()
        {
            foreach (Control previousBtn in panelMenu.Controls)
            {
                if (previousBtn.GetType() != typeof(Button))
                    continue;
                // 클릭 전 버튼 상태로 복구
                previousBtn.BackColor = Color.FromArgb(51, 51, 76);
                previousBtn.ForeColor = Color.White;
                previousBtn.Font = new System.Drawing.Font("Arial", 12F, System.Drawing.FontStyle.Bold);
            }
        }

        private void ActiveButton(object btnSender)
        {
            if (btnSender == null || currentButton == (Button)btnSender)
                return;
            DisableButton();
            currentButton = (Button)btnSender;
            // 클릭 후 버튼 상태로 변화
            currentButton.Font = new System.Drawing.Font("Arial", 14F, System.Drawing.FontStyle.Bold);
        }

C#의 기본 WinForm에서 맨위에 테두리 창이 디자인 적으로 예쁘지 않기 때문에 해당 부분을 없애고 따로 창을 움직일 수 있는 이벤트를 주고자 한다.

MouseDown 이벤트 더블클릭

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestWinForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        [DllImport("user32.DLL", EntryPoint = "ReleaseCapture")]
        private extern static void ReleaseCapture();

        [DllImport("user32.DLL", EntryPoint = "SendMessage")]
        private extern static void SendMessage(System.IntPtr hWnd, int wMsg, int wParam, int IParam);

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            ReleaseCapture();
            SendMessage(this.Handle, 0x112, 0xf012, 0);
        }
    }
}

주의점: 창 내리기, 전체화면, 끄기 버튼은 따로 구현해야 한다.

MetroForm Ui: MIT 라이선스의 Winform의 UI를 예쁘게 바꿀 수 있는 UI 프레임워크  

해당 플러그인을 설치 후 Winform의 Form을 상속 받는 코드를 다음과 같이 수정하면 끝

원본 깃허브 링크: https://github.com/dennismagno/metroframework-modern-ui

 

GitHub - dennismagno/metroframework-modern-ui: My humble attempt to bring the new Modern UI alias Metro UI of Windows 8 to .NET

My humble attempt to bring the new Modern UI alias Metro UI of Windows 8 to .NET Windows Forms applications. - GitHub - dennismagno/metroframework-modern-ui: My humble attempt to bring the new Mode...

github.com

 

상황: 버튼을 누르면 같은 프로젝트 내의 다른 Form을 띄우고자 할 때

C#의 프로그램 파일 계층 구조

여기서 버튼을 누르면 같은 솔루션의 HomeWork3Update의 RoiForm을 화면에 나오게 하고자 한다.

참조 추가 그 후

namespace callTestForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            RoiForm roiForm = new RoiForm();
            roiForm.ShowDialog();
        }
    }
}

+ 만약 해당 폼을 열었을 때 다른 폼을 클릭 가능하게 하고 싶다면 ShowDialog() 대신 Show()로 하면 된다.

실행 모습

WinForm을 다루다 보면 간혹 Tap 순서가 엉망으로 되어있어서 불편한 경우가 있는데 순서를 임의로 조정하는 법과 Tap으로 받지 못 하게 하는 방법을 알게되어 정리 해두고자 한다..  

WinForm에서는 TabIndex 가 낮은 순서 부터 차례대로 Tap키 입력시 이동하게 되어있다.

만약 TabStop에 False 를 주게 된다면 해당 컴포넌트는 Tap키를 받을 수 없게 된다.

+ Recent posts