반응형

 

 

루파디움 설치 및 사용법

 

오토핫키 [AHK] 셀레니움 크롬 드라이버 없이 사용하기

안녕하세요, 본 원문은 https://github.com/Xeo786/Rufaydium-Webdriver 의 자료를 가지고 제작되었습니다. 크롬 셀레니움을 사용할때 오토핫키, 혹은 다른 언어도 크롬 드라이버를 사용하였습니다. 이 Rufay

peuming.tistory.com

 

네이버 로그인 페이지 구조 및 테스트 방법

 

오토핫키 [AHK] 루파디움(셀레니움 대용) 네이버 로그인하기-1

Xeo786/Rufaydium-Webdriver / Github https://github.com/Xeo786/Rufaydium-Webdriver 루페디움 깃허브에 들어가서code -> download ZIP 를 눌러 알집으로 다운로드 합시다 알집을 풀면 Lib 폴더를 제외하고 위 이미지처럼

peuming.tistory.com

 

오토핫키 [AHK] 루파디움(셀레니움 대용) 네이버 로그인하기-2

https://peuming.tistory.com/11 오토핫키 [AHK] 셀레니움 크롬 드라이버 없이 사용하기안녕하세요, 본 원문은 https://github.com/Xeo786/Rufaydium-Webdriver 의 자료를 가지고 제작되었습니다. 크롬 셀레니움을 사

peuming.tistory.com

 

 

루파디움을 통해 웹 조작 매크로를 작성하기에 앞서 

 

안녕하세요 

오토핫키 루파디움을 이용한( 셀레니움 대용으로) 동적 페이지를 조작 및 파싱하는 단계 중 가장 기본적인

부분만 빠르고 쉽게 알려드리려고 합니다. 

 

JavaScript , HTML , PHP 등을 몰라도, 간단하게 동적 웹페이지를 조작하고 배울 수 있는 기회를 제공하는 것을 목표로 두고 있습니다.

 

제가 서치능력이 낮아서 인지 몰라도, 루파디움에 대한 한국어 기준으로 자세히 강의를 해주는 블로그를 많이 보지 못했고, 많은 시행착오 끝에 저도 100% 10% 정도 사용하는 정도 까지 능력을 키우게 되었네요.

 

코드들은 초보자들 기준으로 가장 쉽고, 이해하기 편하도록 작성될 예정이며, 코드의 줄 수 를 줄이는 것은 여러분의
몫 입니다. 

 

 

 

네이버 로그인 

네이버 로그인 인터페이스.ahk
0.00MB

 

스크립트에 네이버 로그인을 하기위해 아이디를 입력하면서 실행을 누르는 것보단

인터페이스가 있는 상태가 더 직관적이고 작업하기 편할 것입니다. 

 

스마트구이를 통해 간단한 인터페이스를 구축합시다.

인터페이스의 역활은 아래와 같습니다. 

 

EDIT   아이디 비밀번호를 입력할 수 있는 칸
LISTVIEW   현재 프로그램이 어떤 부분을 지나가고 있으며, 상황을 볼 수 있는 뷰
BUTTON   사용자가 실행을 하기위한 트리거 역활

 

 

#SingleInstance,Force
#Include Lib\Rufaydium.ahk
title:= "N Login"
Gui, Add, Button, x12 y9 w100 h20 +Disabled,ID
Gui, Add, Edit, x122 y9 w100 h20 vid,
Gui, Add, Button, x232 y9 w100 h20 +Disabled,PW
Gui, Add, Edit, x342 y9 w100 h20 +Password vpw,
Gui, Add, ListView, x12 y39 w430 h110 ,no | 상황
Gui, Add, Button, x12 y159 w430 h30 gstart,로그인하기
Gui, Show, x989 y489 h205 w455,% title
Return

return
start:
gui,submit,nohide


return
GuiClose:
ExitApp

 

 

간단한 인터페이스 구축이 되었으면, 각 Edit 및 Button에 v Label 을 달아주시기 바랍니다.

 

 

 

루파디움 WebDriver 사용

Chrome := new Rufaydium(A_WorkingDir "\Lib\chromedriver.exe")

 

Chrome 이라는 변수에

루파디움의 클래스의 인스턴트를 생성합니다. 이때 인스턴스를 생성할 때 생성자에 인수를 전달해야하는데, 

그 위치는, Lib 폴더안에 담겨있는  Chromedriver.exe 입니다. 

 

Page := Chrome.getSessionByUrl(네이버로그인주소)
if !isobject(page){
	Page := Chrome.NewSession()
	Page.Navigate(네이버로그인주소)
}else{
	msgbox,64,안내, 객체오류입니다
	return
}

 

 

Page := Chrome.getSessionByUrl(네이버로그인주소)

 

Chorme 변수에 할당된 객체에 getSessionByUrl 메서드를 호출하여, 네이버로그인 주소 URL에 세션을 Page 변수에 담습니다.

 

if !isobject(page){
	Page := Chrome.NewSession()
	Page.Navigate(네이버로그인주소)
}else{
	msgbox,64,안내, 객체오류입니다. 관리자에게 문의주세요
	return
}

 

if !isobject(Page) 함수는 변수가 객체인지 아닌지 여부를 판단합니다. 

만약, page 변수가 객체가 아니라면, Chrome 객체에 새로운 세션을 제공하여,

page변수에 담고 네이버 로그인 주소로 접속합니다.

 

pag변수가 객체라면, 메세지를 띄우고 스크립트를 종료합니다. 

 

Page.cdp.QuerySelector("#id").sendkey(id)
Page.getElementsByName("id")[0].SendKey(key.tab) ;ArrowDown
Page.cdp.QuerySelector("#pw").sendkey(pw)
Page.getElementsByName("pw")[0].SendKey(key.enter) ;ArrowDown

 

1. Page 객체에 cdp 형식의 QuerySelector 메소드를 호출하고 sendkey(id) 아이디 값을 적용합니다.

이때 id 값은 gui v라벨의 id 값을 가져옵니다. 

 

2. 1번과 동일하게 메서드를 호출하고 ( cdp X ) key.tab 값을 호출합니다. 

 

3. Page 객체에 cdp 형식의 QuerySelector 메소드를 호출하고 sendkey(pw) 패스워드 값을 적용합니다.

이때 pw 값은 gui v라벨의 id 값을 가져옵니다. 

 

4.  1번과 동일하게 메서드를 호출하고 ( cdp X ) key.enter 값을 호출합니다. 

 

 

 

완성 코드

#SingleInstance, Force
#Include Lib\Rufaydium.ahk
title:= "N Login"
Gui, Add, Button, x12 y9 w100 h20 +Disabled,ID
Gui, Add, Edit, x122 y9 w100 h20 vid,
Gui, Add, Button, x232 y9 w100 h20 +Disabled,PW
Gui, Add, Edit, x342 y9 w100 h20 +Password vpw,
Gui, Add, ListView, x12 y39 w430 h110 ,no | 상황
Gui, Add, Button, x12 y159 w430 h30 gstart,로그인하기
Gui, Show, x989 y489 h205 w455,% title

global naver_login_site := "https://nid.naver.com/nidlogin.login"
LV_Add(,LV_GetCount()+1,"프로그램 시작")
Return

return
start:
gui,submit,nohide
Chrome := new Rufaydium(A_WorkingDir "\Lib\chromedriver.exe")
Page := Chrome.getSessionByUrl(naver_login_site)
if !isobject(page){
	Page := Chrome.NewSession()
	Page.Navigate(naver_login_site)
}else{
	msgbox,64,안내, 객체오류입니다. 관리자에게 문의주세요
	return
}

Page.cdp.QuerySelector("#id").sendkey(id)
Page.getElementsByName("id")[0].SendKey(key.tab) ;ArrowDown
LV_Add(,LV_GetCount()+1,"아이디 입력")
Page.cdp.QuerySelector("#pw").sendkey(pw)
Page.getElementsByName("pw")[0].SendKey(key.enter) ;ArrowDown
LV_Add(,LV_GetCount()+1,"패스워드 입력 및 로그인시도")

return
GuiClose:
ExitApp

 

네이버 로그인.ahk
0.00MB

 

루파디움 Rufaydium.ahk 라이브러리는, 페이지가 호출 , 리디렉션 및 페이지 로딩을 자동으로 기다려줍니다. 

따로, 페이지에 대한 정보를 통해 페이지가 변경되었구나 라는 조건을 따로 적용해주실 필요없습니다.

 

다만 네이버 로그인 페이지 같은경우에는, 동적 페이지가 아니므로 가능한 경우입니다.

 

 

 

 

예외 : 로그인 실패시

사용자가 로그인에 실패했을 경우의 변수도 생각해야합니다.

이때 네이버 로그인을 실패했을 경우, 여러가지 환경을 확인해봐야할 필요가 있습니다.

 

  사용자가 아이디를 입력하지 않았을때    사용자가 비밀번호를 입력하지 않았을때
  사용자가 아이디 및 비밀번호를 입력하지 않았을때 아이디 및 비밀번호가 틀렸을
실패했을때 URL 주소가 변경되는가? 반대로 로그인 성공시와 실패시 페이지의 차이점

 

여러가지 확인 법이 있지만 대체적으로 이렇게 예외상황에 대한 환경을 분석하여

예외처리를 할 수있습니다.

 

아주간단하게, 로그인시 네이버 페이지가 변화하고 

네이버 메인 홈 호출되는 부분을 볼 수 있는데요 .

 

 

 

로그아웃, 로그인 부분을 체크해볼 것입니다

로그인 페이지에 보여지지 않은, 혹은 로그아웃 이라는 글자가 있다면, 로그인성공으로 본다.라고 정의를 내리고 

코드를 작성해봅시다. 

( Page.Html 을 사용할 예정이라서, 만약 다른 사이트에서 페이지 내부 <!------ 로그아웃 시 ------> 이러한 주석 코드가 있다면 다른 방법으로 하셔야합니다 .)

 

 

#SingleInstance, Force
#Include Lib\Rufaydium.ahk
title:= "N Login"
Gui, Add, Button, x12 y9 w100 h20 +Disabled,ID
Gui, Add, Edit, x122 y9 w100 h20 vid,
Gui, Add, Button, x232 y9 w100 h20 +Disabled,PW
Gui, Add, Edit, x342 y9 w100 h20 +Password vpw,
Gui, Add, ListView, x12 y39 w430 h110 ,no | 상황
Gui, Add, Button, x12 y159 w430 h30 gstart,로그인하기
Gui, Show, x989 y489 h205 w455,% title

global naver_login_site := "https://nid.naver.com/nidlogin.login"
LV_Add(,LV_GetCount()+1,"프로그램 시작")
Return

return
start:
gui,submit,nohide
Chrome := new Rufaydium(A_WorkingDir "\Lib\chromedriver.exe")
Page := Chrome.getSessionByUrl(naver_login_site)
if !isobject(page){
	Page := Chrome.NewSession()
	Page.Navigate(naver_login_site)
}else{
	msgbox,64,안내, 객체오류입니다. 관리자에게 문의주세요
	return
}

Page.cdp.QuerySelector("#id").sendkey(id)
Page.getElementsByName("id")[0].SendKey(key.tab) ;ArrowDown
LV_Add(,LV_GetCount()+1,"아이디 입력")
Page.cdp.QuerySelector("#pw").sendkey(pw)
Page.getElementsByName("pw")[0].SendKey(key.enter) ;ArrowDown
LV_Add(,LV_GetCount()+1,"패스워드 입력 및 로그인시도")


Data := Page.html
RegExMatch(data,"로그아웃",Check_ver)
if(Check_ver != ""){
LV_Add(,LV_GetCount()+1,"로그인 성공")
}else{
LV_Add(,LV_GetCount()+1,"로그인 실패")
}



return
GuiClose:
ExitApp

 

 

 

프로그램 종료시 실행된 ChromeDriver 종료까지

#SingleInstance, Force
#Include Lib\Rufaydium.ahk
title:= "N Login"
Gui, Add, Button, x12 y9 w100 h20 +Disabled,ID
Gui, Add, Edit, x122 y9 w100 h20 vid,
Gui, Add, Button, x232 y9 w100 h20 +Disabled,PW
Gui, Add, Edit, x342 y9 w100 h20 +Password vpw,
Gui, Add, ListView, x12 y39 w430 h110 ,no | 상황
Gui, Add, Button, x12 y159 w430 h30 gstart,로그인하기
Gui, Show, x989 y489 h205 w455,% title

global naver_login_site := "https://nid.naver.com/nidlogin.login"
LV_Add(,LV_GetCount()+1,"프로그램 시작")
Return

return
start:
gui,submit,nohide
Chrome := new Rufaydium(A_WorkingDir "\Lib\chromedriver.exe")
Page := Chrome.getSessionByUrl(naver_login_site)
if !isobject(page){
	Page := Chrome.NewSession()
	Page.Navigate(naver_login_site)
}else{
	msgbox,64,안내, 객체오류입니다. 관리자에게 문의주세요
	return
}

Page.cdp.QuerySelector("#id").sendkey(id)
Page.getElementsByName("id")[0].SendKey(key.tab) ;ArrowDown
LV_Add(,LV_GetCount()+1,"아이디 입력")
Page.cdp.QuerySelector("#pw").sendkey(pw)
Page.getElementsByName("pw")[0].SendKey(key.enter) ;ArrowDown
LV_Add(,LV_GetCount()+1,"패스워드 입력 및 로그인시도")


Data := Page.html
RegExMatch(data,"로그아웃",Check_ver)
if(Check_ver != ""){
LV_Add(,LV_GetCount()+1,"로그인 성공")
}else{
LV_Add(,LV_GetCount()+1,"로그인 실패")
}



return
Page_exit(){
	Page.close()
	Page.exit()
	Chrome.QuitAllSessions()
	Chrome.Driver.Exit() ; then exits driver
return
}
Return
GuiClose:
Page_exit()
ExitApp
return

 

네이버 로그인.ahk
0.00MB

 

반응형
반응형

#SingleInstance,Force
title:= "진행 테스트"
Gui, Add, Button, x12 y9 w100 h20 +Disabled,횟수
Gui, Add, Edit, x122 y9 w110 h20 +number +center vcount,
Gui, Add, Button, x242 y9 w100 h20 +Disabled,딜레이(초)
Gui, Add, Edit, x352 y9 w110 h20 +number +center vde,
Gui, Add, Button, x12 y39 w100 h20 +Disabled,진행사항
Gui, Add, Progress, x122 y39 w340 h20 vpb,0
Gui, Add, Button, x12 y69 w450 h30 gstart,시작하기
Gui, Show, x1183 y393 h113 w478,% title
Return
start:
gui,submit,nohide
Loop,% count
{
	guicontrolget,count
	GuiControl,, pb, % A_index / count * 100
	guicontrol,,count,% count-1
	sleep,% de*1000
}
return
GuiClose:
ExitApp

진행상황.ahk
0.00MB

 

 

 

 

 

#GUIProgress #ProgressBar #ProgressIndicator #LoadingSpinner #ProgressCircle #GUIProgramming #UserInterface #UXDesign #UserExperience #LoadingAnimation #LoadingBar #LoadingIndicator #LoadingScreen #ProgressTracking #UIComponents #UIDesign #UIProgress #UserFeedback #TaskProgress #ProgressVisualization #RealTimeProgress #IndeterminateProgress #DeterminateProgress #ProgressBarDesign #LoadingUI #ProgressUX #AsyncProgress #ProgressBarExample #CustomProgressBar #SmoothProgress #ProgressAnimation #ProgressUI #LoadingFeedback #TaskCompletion #InteractiveUI #LoadingScreenDesign #ProgressBarStyles #ProgressComponent #ProgressUpdates #UIElements #UserInterfaceDesign #LoadingExperience #ProgressIndicatorDesign #AnimatedProgressBar #ProgressVisualization #LoadingComponent #UserGuidance #TaskIndicator #GUIElements #LoadingExperience #ProgressWidget #LoadingEffect #ProgressFeedback #ResponsiveProgressBar #ProgressMeter #LoadingCircle #UXProgress #RealTimeFeedback #ProgressMonitor #Task #GUI진행상황 #진행막대 #진행표시기 #로딩스피너 #진행원 #GUI프로그래밍 #사용자인터페이스 #UX디자인 #사용자경험 #로딩애니메이션 #로딩바 #로딩표시기 #로딩화면 #진행추적 #UI구성요소 #UI디자인 #UI진행상황 #사용자피드백 #작업진행상황 #진행시각화 #실시간진행상황 #불확정진행상황 #확정진행상황 #진행막대디자인 #로딩UI #진행UX #비동기진행상황 #진행막대예시 #맞춤진행막대 #부드러운진행상황 #진행애니메이션 #진행UI #로딩피드백 #작업완료 #인터랙티브UI #로딩화면디자인 #진행막대스타일 #진행구성요소 #진행상황업데이트 #UI요소 #사용자인터페이스디자인 #로딩경험 #진행표시기디자인 #애니메이션진행막대 #진행시각화 #로딩구성요소 #사용자안내 #작업표시기 #GUI요소 #로딩경험 #진행위젯 #로딩효과 #진행피드백 #반응형진행막대 #진행미터 #로딩원 #UX진행상황 #실시간피드백 #진행모니터 #작업진행UI #사용자알림 #비동기로딩 #진행막대통합 #진행도표시 #진행도 #작업진행 #로딩진행 #UI프로그레스 #프로그레스바 #사용자진행 #인터페이스디자인 #시각적진행 #진행디자인 #진행애니메이션디자인 #UX로딩 #프로세스진행 #작업진행도 #로딩진행상황 #실시간로딩 #작업피드백 #진행현황 #진행바 #진행상태 #작업알림 #시각적피드백 #진행도체크 #진행상황디자인 #프로세스추적 #진행상태표시 #진행체크 #진행시각화도구 #진행현황알림

반응형
반응형

 

GUI, Progress, SplashImage

명령어에 사용합니다.

 

gui, font, s10, Verdana
SplashImage [, ImageFile, Options, SubText, MainText, WinTitle, FontName]
Progress, ProgressParam1 [, SubText, MainText, WinTitle, FontName]

 

 

글꼴 이름 win95 WinNet Win98 Win2000 WinMe winXP
Abadi MT Condensed Light     x      
Arial x x x x x x
Arial Alternative Regular         x  
Arial Alternative Symbol         x  
Arial Black     x x x x
Arial Bold x x x x x x
Arial Bold Italic x x x x x x
Arial Italic x x x x x x
Book Antiqua     x      
Calisto MT     x      
Century Gothic     x      
Century Gothic Bold     x      
Century Gothic Bold Italic     x      
Century Gothic Italic     x      
Comic Sans MS     x x x  
Comic Sans MS Bold     x x x x
Copperplate Gothic Bold     x      
Copperplate Gothic Light     x      
Courier x x x x x x
Courier New x x x x x x
Courier New Bold x x x x x x
Courier New Bold Italic x x x x x x
Courier New Italic x x x x x x
Estrangelo Edessa           x
Franklin Gothic Medium           x
Franklin Gothic Medium Italic         x  
Gautami           x
Georgia       x   x
Georgia Bold       x   x
Georgia Bold Italic       x   x
Georgia Italic       x   x
Georgia Italic Impact           x
Impact     x x x  
Latha           x
Lucida Console   x x x x x
Lucida Handwriting Italic     x      
Lucida Sans Italic     x      
Lucida Sans Unicode     x x   x
Marlett     x   x  
Matisse ITC     x      
Modern x x x x    
Modern MS Sans Serif           x
MS Sans Serif x x x x x x
MS Serif x x x x x  
Mv Boli           x
News Gothic MT     x      
News Gothic MT Bold     x      
News Gothic MT Italic     x      
OCR A Extended     x      
Palatino Linotype       x   x
Palatino Linotype Bold       x   x
Palatino Linotype Bold Italic     x   x  
Palatino Linotype Italic       x   x
Roman   x   x   x
Script   x   x   x
Small Fonts   x   x   x
Smallfonts x   x   x  
Symbol x x x x x x
Tahoma     x x x x
Tahoma Bold     x x x x
Tempus Sans ITC     x x    
Times New Roman x x x x x x
Times New Roman Bold x x x x x x
Times New Roman Bold Italic x x x x x x
Times New Roman Italic x x x x x x
Trebuchet         x  
Trebuchet Bold         x  
Trebuchet Bold Italic         x  
Trebuchet Italic         x  
Trebuchet MS       x   x
Trebuchet MS Bold       x   x
Trebuchet MS Bold Italic       x   x
Trebuchet MS Italic       x   x
Tunga           x
Verdana (included with MSIE 3+)     x x x x
Verdana Bold     x x x x
Verdana Bold Italic     x x x x
Verdana Italic     x x x x
Webdings     x x x x
Westminster     x   x x
Wingdings x x   x   x
WST_Czech           x
WST_Engl           x
WST_Fren           x
WST_Germ           x
WST_Ital           x
WST_Span           x
WST_Swed            

 

반응형
반응형

 

 

UWP API를 사용한 OCR 광학 문자 인식입니다.

원문 주소 : https://www.autohotkey.com/boards/viewtopic.php?t=72674

UWP API 참고 주소 : https://learn.microsoft.com/en-us/uwp/api/windows.media.ocr?view=winrt-22621

 

Windows.Media.Ocr Namespace - Windows UWP applications

Provides optical character recognition (OCR) API for reading text from images.

learn.microsoft.com

 

UWP

UWP(Universal Windows Platform)은 Microsoft가 개발한 응용 프로그램 플랫폼입니다. UWP의 주요 목표는 Windows 운영 체제를 사용하는 모든 장치에서 실행되는 응용 프로그램을 쉽게 개발할 수 있도록 하는 것입니다.

이를 통해 개발자는 한 번의 코드 작성으로 PC, 태블릿, 스마트폰, Xbox, HoloLens 등

다양한 장치에서 동일한 응용 프로그램을 실행할 수 있습니다.

 

 

msgbox % ocr("ShowAvailableLanguages")
msgbox % ocr("test.jpg", "en")
msgbox % ocr("test.jpg", "ru")
msgbox % ocr("test.jpg")
ExitApp

ocr(file, lang := "FirstFromAvailableLanguages")
{
   static OcrEngineStatics, OcrEngine, MaxDimension, LanguageFactory, Language, CurrentLanguage, BitmapDecoderStatics, GlobalizationPreferencesStatics
   if (OcrEngineStatics = "")
   {
      CreateClass("Windows.Globalization.Language", ILanguageFactory := "{9B0252AC-0C27-44F8-B792-9793FB66C63E}", LanguageFactory)
      CreateClass("Windows.Graphics.Imaging.BitmapDecoder", IBitmapDecoderStatics := "{438CCB26-BCEF-4E95-BAD6-23A822E58D01}", BitmapDecoderStatics)
      CreateClass("Windows.Media.Ocr.OcrEngine", IOcrEngineStatics := "{5BFFA85A-3384-3540-9940-699120D428A8}", OcrEngineStatics)
      DllCall(NumGet(NumGet(OcrEngineStatics+0)+6*A_PtrSize), "ptr", OcrEngineStatics, "uint*", MaxDimension)   ; MaxImageDimension
   }
   if (file = "ShowAvailableLanguages")
   {
      if (GlobalizationPreferencesStatics = "")
         CreateClass("Windows.System.UserProfile.GlobalizationPreferences", IGlobalizationPreferencesStatics := "{01BF4326-ED37-4E96-B0E9-C1340D1EA158}", GlobalizationPreferencesStatics)
      DllCall(NumGet(NumGet(GlobalizationPreferencesStatics+0)+9*A_PtrSize), "ptr", GlobalizationPreferencesStatics, "ptr*", LanguageList)   ; get_Languages
      DllCall(NumGet(NumGet(LanguageList+0)+7*A_PtrSize), "ptr", LanguageList, "int*", count)   ; count
      loop % count
      {
         DllCall(NumGet(NumGet(LanguageList+0)+6*A_PtrSize), "ptr", LanguageList, "int", A_Index-1, "ptr*", hString)   ; get_Item
         DllCall(NumGet(NumGet(LanguageFactory+0)+6*A_PtrSize), "ptr", LanguageFactory, "ptr", hString, "ptr*", LanguageTest)   ; CreateLanguage
         DllCall(NumGet(NumGet(OcrEngineStatics+0)+8*A_PtrSize), "ptr", OcrEngineStatics, "ptr", LanguageTest, "int*", bool)   ; IsLanguageSupported
         if (bool = 1)
         {
            DllCall(NumGet(NumGet(LanguageTest+0)+6*A_PtrSize), "ptr", LanguageTest, "ptr*", hText)
            buffer := DllCall("Combase.dll\WindowsGetStringRawBuffer", "ptr", hText, "uint*", length, "ptr")
            text .= StrGet(buffer, "UTF-16") "`n"
         }
         ObjRelease(LanguageTest)
      }
      ObjRelease(LanguageList)
      return text
   }
   if (lang != CurrentLanguage) or (lang = "FirstFromAvailableLanguages")
   {
      if (OcrEngine != "")
      {
         ObjRelease(OcrEngine)
         if (CurrentLanguage != "FirstFromAvailableLanguages")
            ObjRelease(Language)
      }
      if (lang = "FirstFromAvailableLanguages")
         DllCall(NumGet(NumGet(OcrEngineStatics+0)+10*A_PtrSize), "ptr", OcrEngineStatics, "ptr*", OcrEngine)   ; TryCreateFromUserProfileLanguages
      else
      {
         CreateHString(lang, hString)
         DllCall(NumGet(NumGet(LanguageFactory+0)+6*A_PtrSize), "ptr", LanguageFactory, "ptr", hString, "ptr*", Language)   ; CreateLanguage
         DeleteHString(hString)
         DllCall(NumGet(NumGet(OcrEngineStatics+0)+9*A_PtrSize), "ptr", OcrEngineStatics, ptr, Language, "ptr*", OcrEngine)   ; TryCreateFromLanguage
      }
      if (OcrEngine = 0)
      {
         msgbox Can not use language "%lang%" for OCR, please install language pack.
         ExitApp
      }
      CurrentLanguage := lang
   }
   if (SubStr(file, 2, 1) != ":")
      file := A_ScriptDir "\" file
   if !FileExist(file) or InStr(FileExist(file), "D")
   {
      msgbox File "%file%" does not exist
      ExitApp
   }
   VarSetCapacity(GUID, 16)
   DllCall("ole32\CLSIDFromString", "wstr", IID_RandomAccessStream := "{905A0FE1-BC53-11DF-8C49-001E4FC686DA}", "ptr", &GUID)
   DllCall("ShCore\CreateRandomAccessStreamOnFile", "wstr", file, "uint", Read := 0, "ptr", &GUID, "ptr*", IRandomAccessStream)
   DllCall(NumGet(NumGet(BitmapDecoderStatics+0)+14*A_PtrSize), "ptr", BitmapDecoderStatics, "ptr", IRandomAccessStream, "ptr*", BitmapDecoder)   ; CreateAsync
   WaitForAsync(BitmapDecoder)
   BitmapFrame := ComObjQuery(BitmapDecoder, IBitmapFrame := "{72A49A1C-8081-438D-91BC-94ECFC8185C6}")
   DllCall(NumGet(NumGet(BitmapFrame+0)+12*A_PtrSize), "ptr", BitmapFrame, "uint*", width)   ; get_PixelWidth
   DllCall(NumGet(NumGet(BitmapFrame+0)+13*A_PtrSize), "ptr", BitmapFrame, "uint*", height)   ; get_PixelHeight
   if (width > MaxDimension) or (height > MaxDimension)
   {
      msgbox Image is to big - %width%x%height%.`nIt should be maximum - %MaxDimension% pixels
      ExitApp
   }
   BitmapFrameWithSoftwareBitmap := ComObjQuery(BitmapDecoder, IBitmapFrameWithSoftwareBitmap := "{FE287C9A-420C-4963-87AD-691436E08383}")
   DllCall(NumGet(NumGet(BitmapFrameWithSoftwareBitmap+0)+6*A_PtrSize), "ptr", BitmapFrameWithSoftwareBitmap, "ptr*", SoftwareBitmap)   ; GetSoftwareBitmapAsync
   WaitForAsync(SoftwareBitmap)
   DllCall(NumGet(NumGet(OcrEngine+0)+6*A_PtrSize), "ptr", OcrEngine, ptr, SoftwareBitmap, "ptr*", OcrResult)   ; RecognizeAsync
   WaitForAsync(OcrResult)
   DllCall(NumGet(NumGet(OcrResult+0)+6*A_PtrSize), "ptr", OcrResult, "ptr*", LinesList)   ; get_Lines
   DllCall(NumGet(NumGet(LinesList+0)+7*A_PtrSize), "ptr", LinesList, "int*", count)   ; count
   loop % count
   {
      DllCall(NumGet(NumGet(LinesList+0)+6*A_PtrSize), "ptr", LinesList, "int", A_Index-1, "ptr*", OcrLine)
      DllCall(NumGet(NumGet(OcrLine+0)+7*A_PtrSize), "ptr", OcrLine, "ptr*", hText) 
      buffer := DllCall("Combase.dll\WindowsGetStringRawBuffer", "ptr", hText, "uint*", length, "ptr")
      text .= StrGet(buffer, "UTF-16") "`n"
      ObjRelease(OcrLine)
   }
   Close := ComObjQuery(IRandomAccessStream, IClosable := "{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}")
   DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), "ptr", Close)   ; Close
   ObjRelease(Close)
   Close := ComObjQuery(SoftwareBitmap, IClosable := "{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}")
   DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), "ptr", Close)   ; Close
   ObjRelease(Close)
   ObjRelease(IRandomAccessStream)
   ObjRelease(BitmapDecoder)
   ObjRelease(BitmapFrame)
   ObjRelease(BitmapFrameWithSoftwareBitmap)
   ObjRelease(SoftwareBitmap)
   ObjRelease(OcrResult)
   ObjRelease(LinesList)
   return text
}



CreateClass(string, interface, ByRef Class)
{
   CreateHString(string, hString)
   VarSetCapacity(GUID, 16)
   DllCall("ole32\CLSIDFromString", "wstr", interface, "ptr", &GUID)
   result := DllCall("Combase.dll\RoGetActivationFactory", "ptr", hString, "ptr", &GUID, "ptr*", Class)
   if (result != 0)
   {
      if (result = 0x80004002)
         msgbox No such interface supported
      else if (result = 0x80040154)
         msgbox Class not registered
      else
         msgbox error: %result%
      ExitApp
   }
   DeleteHString(hString)
}

CreateHString(string, ByRef hString)
{
    DllCall("Combase.dll\WindowsCreateString", "wstr", string, "uint", StrLen(string), "ptr*", hString)
}

DeleteHString(hString)
{
   DllCall("Combase.dll\WindowsDeleteString", "ptr", hString)
}

WaitForAsync(ByRef Object)
{
   AsyncInfo := ComObjQuery(Object, IAsyncInfo := "{00000036-0000-0000-C000-000000000046}")
   loop
   {
      DllCall(NumGet(NumGet(AsyncInfo+0)+7*A_PtrSize), "ptr", AsyncInfo, "uint*", status)   ; IAsyncInfo.Status
      if (status != 0)
      {
         if (status != 1)
         {
            DllCall(NumGet(NumGet(AsyncInfo+0)+8*A_PtrSize), "ptr", AsyncInfo, "uint*", ErrorCode)   ; IAsyncInfo.ErrorCode
            msgbox AsyncInfo status error: %ErrorCode%
            ExitApp
         }
         ObjRelease(AsyncInfo)
         break
      }
      sleep 10
   }
   DllCall(NumGet(NumGet(Object+0)+8*A_PtrSize), "ptr", Object, "ptr*", ObjectResult)   ; GetResults
   ObjRelease(Object)
   Object := ObjectResult
}

 

test.zip
0.00MB

 

 

 

이미지 ( JPG (JPEG), BMP , PNG , WEBG , webp 등 되는 것 같습니다.

이미지의 글자를 인식 및 추출 할 수있으며 ,

텍스트 글자의 갯수 및 종류, 키워드, 단어 등을 추출하여 만들 수있는 프로그램은 무궁무진 합니다.

   

반응형

+ Recent posts