Windows-F# 및 표준 기능을 사용하여 영역을 선택하는 OCR
개요
화면 캡처 촬영 프로그램'캡처 & 스케치[1]'와'윈도s.Media.Ocr[2]'를 조합하여 F#로 선택한 영역의 텍스트를 읽는 프로그램을 만든다.
전역 핫키 시작 영역 선택을 통해 읽은 텍스트를 클립보드에 저장하는 작업 트레이 상주 응용 프로그램입니다.
환경 만들기
대상
릴리즈
Windows
20H2 (19042.928)
.NET SDK
5.0.202
설치 예
※'커팅 & 스케치'설정'자동 클립보드로 복사'를 엽니다.
.fsproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows10.0.19041.0</TargetFramework>
<RootNamespace>プロジェクト名</RootNamespace>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
</Project>
Program.fsopen System
let await (i: Windows.Foundation.IAsyncOperation<'TResult>) =
i.AsTask() |> Async.AwaitTask
let startScreenclip () =
let cmd = new System.Diagnostics.ProcessStartInfo "cmd"
cmd.Arguments <- @"/c start ms-screenclip:"
cmd.UseShellExecute <- true
cmd.WindowStyle <- System.Diagnostics.ProcessWindowStyle.Hidden
let cmdProcess = System.Diagnostics.Process.Start cmd
cmdProcess.WaitForExit()
let processArray = System.Diagnostics.Process.GetProcessesByName "ScreenClippingHost"
processArray.[0].WaitForExit()
let getClipboardBitmap () =
let bitmapSource = System.Windows.Clipboard.GetImage()
if bitmapSource <> null then
let bitmapFrame = System.Windows.Media.Imaging.BitmapFrame.Create bitmapSource
let encoder = new System.Windows.Media.Imaging.BmpBitmapEncoder()
encoder.Frames.Add bitmapFrame
use memoryStream = new System.IO.MemoryStream()
encoder.Save memoryStream
let byteArray = memoryStream.ToArray()
use randomAccessStream = new Windows.Storage.Streams.InMemoryRandomAccessStream()
use outputStream = randomAccessStream.GetOutputStreamAt(uint64 0)
use dataWriter = new Windows.Storage.Streams.DataWriter(outputStream)
dataWriter.WriteBytes byteArray
async {
let! _ = await <| dataWriter.StoreAsync()
let! _ = await <| outputStream.FlushAsync()
let! decoder = await <| Windows.Graphics.Imaging.BitmapDecoder.CreateAsync randomAccessStream
let! softwareBitmap = await <| decoder.GetSoftwareBitmapAsync(Windows.Graphics.Imaging.BitmapPixelFormat.Bgra8, Windows.Graphics.Imaging.BitmapAlphaMode.Premultiplied)
return softwareBitmap
}
|> Async.RunSynchronously
else
null
let startOCR bitmap =
let ocrEngine = Windows.Media.Ocr.OcrEngine.TryCreateFromUserProfileLanguages()
if bitmap <> null then
async {
let! ocrResult = await <| ocrEngine.RecognizeAsync bitmap
return ocrResult.Text
}
|> Async.RunSynchronously
else
""
let createIcon () =
let toolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(Text = "&終了")
toolStripMenuItem.Click.Add(fun e -> System.Windows.Forms.Application.Exit())
let contextMenuStrip = new System.Windows.Forms.ContextMenuStrip()
contextMenuStrip.Items.Add toolStripMenuItem |> ignore
new System.Windows.Forms.NotifyIcon(
Icon = new System.Drawing.Icon @".\icon.ico",
Visible = true,
Text = "TestApp",
ContextMenuStrip = contextMenuStrip
)
[<System.Runtime.InteropServices.DllImport("user32.dll")>]
extern int RegisterHotKey(IntPtr HWnd, int ID, int MOD_KEY, int KEY)
[<System.Runtime.InteropServices.DllImport("user32.dll")>]
extern int UnregisterHotKey(IntPtr HWnd, int ID)
type HotkeyForm () as this =
inherit System.Windows.Forms.Form()
let icon = createIcon()
do
RegisterHotKey(this.Handle, 0x0000, 0x0001 ||| 0x0008, int System.Windows.Forms.Keys.C) |> ignore
System.Windows.Forms.Application.ApplicationExit.Add(fun e ->
UnregisterHotKey(this.Handle, 0x0000) |> ignore
)
override this.WndProc m =
base.WndProc(&m)
if m.Msg = 0x0312 && int m.WParam = 0x0000 then
startScreenclip()
System.Windows.Clipboard.SetText(startOCR <| getClipboardBitmap())
interface IDisposable with
member this.Dispose() =
icon.Dispose()
[<STAThread>]
do
use form = new HotkeyForm()
System.Windows.Forms.Application.Run()
해설
커팅 & 스케치
[잘라내기 & 스케치] 클립보드에 선택 영역의 이미지를 저장하는 기능을 사용합니다.
let startScreenclip () =
// コマンドプロンプト
let cmd = new System.Diagnostics.ProcessStartInfo "cmd"
// 「ms-screenclip:」新規切り取りを開始する URI スキーム
cmd.Arguments <- @"/c start ms-screenclip:"
cmd.UseShellExecute <- true
cmd.WindowStyle <- System.Diagnostics.ProcessWindowStyle.Hidden
// 「切り取り&スケッチ」の起動
let cmdProcess = System.Diagnostics.Process.Start cmd
cmdProcess.WaitForExit()
// 「切り取り&スケッチ」の終了待機
let processArray = System.Diagnostics.Process.GetProcessesByName "ScreenClippingHost"
processArray.[0].WaitForExit()
클립보드에서 이미지 가져오기
let getClipboardBitmap () =
// WPF の機能を利用
let bitmapSource = System.Windows.Clipboard.GetImage()
if bitmapSource <> null then
// 以下「Windows.Media.Ocr」が認識できる SoftwareBitmap に変換する処理
let bitmapFrame = System.Windows.Media.Imaging.BitmapFrame.Create bitmapSource
let encoder = new System.Windows.Media.Imaging.BmpBitmapEncoder()
encoder.Frames.Add bitmapFrame
use memoryStream = new System.IO.MemoryStream()
encoder.Save memoryStream
let byteArray = memoryStream.ToArray()
use randomAccessStream = new Windows.Storage.Streams.InMemoryRandomAccessStream()
use outputStream = randomAccessStream.GetOutputStreamAt(uint64 0)
use dataWriter = new Windows.Storage.Streams.DataWriter(outputStream)
dataWriter.WriteBytes byteArray
async {
let! _ = await <| dataWriter.StoreAsync()
let! _ = await <| outputStream.FlushAsync()
let! decoder = await <| Windows.Graphics.Imaging.BitmapDecoder.CreateAsync randomAccessStream
let! softwareBitmap = await <| decoder.GetSoftwareBitmapAsync(Windows.Graphics.Imaging.BitmapPixelFormat.Bgra8, Windows.Graphics.Imaging.BitmapAlphaMode.Premultiplied)
return softwareBitmap
}
|> Async.RunSynchronously
else
null
Windows.Media.Ocr
글로벌 핫키
역사를 갱신하다
일자
컨텐트
2021/04/26
'커팅 & 스케치' 관련 내용을 추가합니다.
end
각주
'Windows 10 옥토버 2018 업데이트'에 표준으로 탑재된다.↩︎
Windows 10에 표준으로 설치됩니다.↩︎
Reference
이 문제에 관하여(Windows-F# 및 표준 기능을 사용하여 영역을 선택하는 OCR), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/shikatan/articles/6386269c49d5612f48ac텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)