NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • NGM 6
  • 매뉴얼

    NGM 6

    본 사이트의 컨텐츠는 저작권법의 보호를 받으므로 무단 복사, 게재, 배포 등을 금합니다.

    커스텀 대상 이미지에서 원본 이미지를 캡쳐해서 찾는 이미지 서치 커스텀 모듈 액션 만들기.

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 엔지엠 매크로의 이미지 서치와 이미지 매치는 찾을 이미지(원본)를 미리 캡쳐 해놓고, 대상 이미지(윈도우 또는 프로그램)를 계속 캡쳐하면서 찾아주는 기능입니다. 그렇다보니 찾을 원본 이미지가 대상 이미지보다 무조건 작아야하는데요. 이와는 반대로 대상 이미지를 고정해놓고, 찾을 이미지를 계속 캡쳐하는 로직이 필요할수도 있습니다. 이런 경우에는 오늘 배워볼 커스텀 모듈 액션을 사용하면 문제를 쉽게 해결할 수 있을겁니다.

     

    이 예제를 학습하려면 커스텀 모듈 개발 환경을 미리 갖춰야 합니다. 아래 글을 참고하셔서 개발 환경을 만들어보세요.

    커스텀 모듈 개발 환경 만들기 ]

    1부 - 커스텀 모듈로 이미지 서치 액션 만들기 ]

    2부 - 커스텀 모듈로 이미지 서치 액션 만들기 ]

    3부 - 커스텀 모듈로 이미지 서치 액션 만들기 ]

     

    비주얼 스튜디오를 실행하고, 기존 프로젝트에 새 클래스를 추가하세요. 그리고, 이름은 CustomReverseImageSearchModel.cs로 지어줍니다.

    GvXmuMa.png

     

     

    조건 액션으로 만들기 위해 "NGM.Models.Interface.BaseCustomConditionToolModel" 추상 클래스를 상속 받아줍니다.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CustomImageSearch
    {
        [Serializable]
        public class CustomReverseImageSearchModel : NGM.Models.Interface.BaseCustomConditionToolModel
        {
            public override string DisplayCategory => throw new NotImplementedException();
    
            public override string DisplayName => throw new NotImplementedException();
    
            public override bool? Execute()
            {
                throw new NotImplementedException();
            }
        }
    }

     

    카테고리명과 액션명을 설정하세요. 좋은 이름이 떠오르지 않아서 "이미지 역서치"로 지어봤습니다.

            public override string DisplayCategory => "조건";
    
            public override string DisplayName => "이미지 역서치";

     

    결과를 담을 속성을 하나 추가하세요.

            [Category("Data")]
            [DisplayName("찾은 좌표")]
            [Description("대상 이미지에서 찾은 원본 이미지의 좌표입니다.")]
            [Browsable(true)]
            [ReadOnly(true)]
            [DefaultValue(typeof(Point), "0, 0")]
            public Point Result { get; set; }

     

    대상 이미지를 선택할 수 있는 속성 2개를 추가 해주세요. TargetImage 속성은 ngi 이미지를 선택해서 사용할 수 있고, TargetFile은 윈도우 이미지인 gif, jpg, png등등을 선택해서 사용할 수 있습니다. 둘중에 하나만 설정해야 합니다.

            [Category("Action")]
            [DisplayName("대상 이미지")]
            [Description("원본 이미지를 찾을 대상 이미지를 선택하세요.")]
            [Browsable(true)]
            [DefaultValue(null)]
            [TypeConverter(typeof(NGM.Models.TypeConverter.ImageConverter))]
            public string TargetImage { get; set; }
    
            [Category("Action")]
            [DisplayName("대상 이미지 파일")]
            [Description("원본 이미지를 찾을 대상 이미지를 선택하세요.")]
            [Browsable(true)]
            [DefaultValue(null)]
            [Editor(typeof(NGM.Models.TypeEditor.OpenFileSelectorEditor), typeof(UITypeEditor))]
            public string TargetFile { get; set; }

     

    위에서 대상 이미지는 미리 캡쳐한 이미지를 선택하도록 했습니다. 원본 이미지는 찾을 이미지인데요. 찾을 이미지를 실행시마다 현재 상태를 캡쳐해서 비교하도록 해야 합니다. 그래서, 이미지를 선택하는게 아닌 캡쳐 영역을 설정하도록 만들었습니다. 캡쳐 영역이 없으면 윈도우 전체 화면을 캡쳐하게 됩니다.

            [Category("Action")]
            [DisplayName("원본 이미지")]
            [Description("이미지 서치에 사용할 원본 이미지 영역을 선택하세요.")]
            [Browsable(true)]
            [DefaultValue(typeof(System.Drawing.Rectangle), "0,0,0,0")]
            [Editor(typeof(NGM.Models.TypeEditor.AreaCaptureEditor), typeof(System.Drawing.Design.UITypeEditor))]
            public Rectangle SearchArea { get; set; }

     

    이제 원본 이미지와 대상 이미지를 모두 메모리로 올리고, 비교하기만 하면 됩니다. 실행 코드는 아래와 같습니다.

            public override bool? Execute()
            {
                Image target = null;
    
                try
                {
                    if (string.IsNullOrEmpty(TargetFile))
                        target = NGM.Models.Common.Reflection.GetNgmImage(MainView.CurrentScriptView.Player, TargetImage);
                    else
                        target = Image.FromFile(TargetFile);
    
                    Image source = NGM.Utility.ScreenCaptureManager.ScreenShot.GetActiveImage(SearchArea);
                    var rect = NGM.Utility.ImageManager.ImageCondition.IsFind(source, target);
                    Result = NGM.Common.RectangleCenter(rect);
                    return !rect.IsEmpty;
                }
                catch (Exception ex)
                {
                    Result = new Point();
                    Console.WriteLine(ex.Message);
                    return false;
                }
                finally
                {
                    target?.Dispose();
                }
            }

     

    프로젝트를 빌드하고, 배포하세요. 그리고, 엔지엠 매크로 에디터에서 아래와 같이 이미지 역서치 액션을 추가하세요.

    94RiIyx.png

     

     

    대상 이미지를 미리 캡쳐 해두어야 합니다. 저는 아래와 같이 그림판 전체를 캡쳐 했습니다.

    vKmygPU.png

     

     

    계속해서 찾을 원본 이미지는 호롱불입니다. 아래 그림을 참고해서 영역을 설정 해보세요.

    dk4x9ZD.png

     

     

    대상 이미지는 미리 캡쳐해둔 그림판입니다. source.ngi로 저장했기 때문에 이걸 선택하면 됩니다.

    ukY2dfe.png

     

     

    매크로를 실행하면 미리 캡쳐해둔 그림판 이미지에서 윈도우 화면에서 캡쳐한 이미지를 찾습니다.

    P7Tnpt0.png

     

     

    참고로, 결과 값으로 나온 찾은 좌표 237, 134는 윈도우의 현재 상태가 아니기 때문에 이미지를 기준으로 어디에 위치해 있는지를 알려주는 좌표입니다. 따라서, 저 좌표로 클릭 액션을 실행하면 아마도 엉뚱한 위치를 클릭할겁니다. 이미 저장된 대상 이미지를 사용하기 때문에 이미지 크기를 기준으로 0, 0부터 호롱불이 떨어져 있는 위치이기 때문입니다. 만약, 그림판의 대상 이미지를 모니터 해상도 사이즈로 저장하면 좌표도 맞을겁니다. 윈도우 화면과 1:1 좌표계니까요.

     

    뭔가 말이 복잡하고 어려울 수 있는데요. 이미 저장된 이미지를 대상 이미지로 사용하면 윈도우 화면 좌표가 아니라서 클릭할 때는 윈도우 창 위치만큼 좌표를 보정해줘야 합니다. 그림판이 윈도우의 0, 0 기준으로 떨어져 있는 만큼의 좌표 보정입니다. 아마도, 이런식으로 이미지를 비교하는거면 클릭하는데 사용할 용도는 아닐겁니다. 편집된 전체 이미지에서 현재 위치가 어딘지 찾기 위해서 응용할 수 있을듯 합니다.

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.