위의 링크 된 다른 게시물의 향상된 코드는 WinRT 비동기 개체를 F # Async<_>
에 매핑하여 일부 형식을 훨씬 더 즐겁게 만듭니다.
open System.Reflection
type Asyncifier() =
static let winrtExts = System.Type.GetType("System.WindowsRuntimeSystemExtensions, System.Runtime.WindowsRuntime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
static let asTask = winrtExts.GetMethods() |> Seq.find(fun m -> m.Name = "AsTask" && m.IsGenericMethodDefinition && m.GetGenericArguments().Length = 1 && m.ReturnType.IsGenericType)
static member FromTask<'t,'u>(t:System.Threading.Tasks.Task<'t>) =
async {
let! t = Async.AwaitTask t
return box t :?> 'u
}
static member FromIAsyncObjThrough<'t>(argTy, o) : Async<'t> =
typeof<Asyncifier>.GetMethod("FromTask").MakeGenericMethod(argTy, typeof<'t>).Invoke(null, [| asTask.MakeGenericMethod(argTy).Invoke(null, [|o|]) |]) :?> _
let getWindowsType (name:string) =
let ns = let parts = name.Split('.') in parts.[0] + "." + parts.[1]
System.Type.GetType(sprintf "%s, %s, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime" name ns)
let IAsyncOperation = getWindowsType "Windows.Foundation.IAsyncOperation`1"
let (?) (o:obj) s : 'a =
let rec build ty args =
if Reflection.FSharpType.IsFunction ty then
let dom, rng = Reflection.FSharpType.GetFunctionElements ty
let mkArgs =
if dom = typeof<unit> then
if Reflection.FSharpType.IsFunction rng then failwith "Unit as non-final argument in curried definition?"
fun _ -> args
else
fun arg -> arg::args
Reflection.FSharpValue.MakeFunction(ty, fun o -> build rng (mkArgs o))
else
let rcvr,ty,flags =
match o with
| :? System.Type as ty -> null,ty,BindingFlags.Static
| _ -> o,o.GetType(),BindingFlags.Instance
let flags = flags ||| BindingFlags.Public
let meth =
if Reflection.FSharpType.IsFunction typeof<'a> then
query {
for m in ty.GetMethods(flags) do
where (m.Name = s)
where (m.GetParameters().Length = args.Length)
exactlyOne
}
else
ty.GetProperty(s, flags).GetGetMethod()
let result = meth.Invoke(rcvr, args |> List.toArray)
let resultTy =
let rec resultTy ty =
if Reflection.FSharpType.IsFunction ty then Reflection.FSharpType.GetFunctionElements ty |> snd |> resultTy
else ty
resultTy typeof<'a>
let (|GenericTypeInstance|_|) (genTy:System.Type) (ty:System.Type) =
if ty.IsGenericType && ty.GetGenericTypeDefinition() = genTy then Some (ty.GetGenericArguments())
else None
let asyncTy = typedefof<Async<_>>
match meth.ReturnType, resultTy with
| GenericTypeInstance IAsyncOperation [|winRtTy|], GenericTypeInstance asyncTy [|returnTy|] ->
// unwrap to F# async
typeof<Asyncifier>.GetMethod("FromIAsyncObjThrough").MakeGenericMethod(returnTy).Invoke(null, [|winRtTy; result|])
| _ -> result
build typeof<'a> [] :?> 'a
그리고 여기 당신이 OCR 작업을 수행하는 데 사용할 수 있습니다 방법은 다음과 같습니다
"내가 사용하고자하는 라이브러리가 UWP 응용 프로그램 내에서만 사용할 수 있기 때문에"
let Language = getWindowsType @"Windows.Globalization.Language"
let OcrEngine = getWindowsType "Windows.Media.Ocr.OcrEngine"
let BitmapDecoder = getWindowsType "Windows.Graphics.Imaging.BitmapDecoder"
let StorageFile = getWindowsType "Windows.Storage.StorageFile"
let enUs = Language.GetConstructor([|typeof<string>|]).Invoke([|"en-US"|])
let engine : obj = OcrEngine?TryCreateFromLanguage enUs
let getTextAsync (path:string) : Async<string> = async {
let! file = StorageFile?GetFileFromPathAsync path
let! stream = file?OpenReadAsync()
let! decoder = BitmapDecoder?CreateAsync stream
let! bitmap = decoder?GetSoftwareBitmapAsync()
let! result = engine?RecognizeAsync bitmap
return result?Text
}
출처
2016-08-18 19:31:49
kvb
=> 먼저 세상을해야합니다 :) – Bart
@Bart Windows.Media.Ocr (https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.ocr)은 저의 이해에 따라 세계 최초입니다 - "도서관은 Windows Phone 및 Windows 스토어 앱에서만 강력한 제한 사항입니다. " @ http://blog.a9t9.com/2015/09/ocr-api.html – bugfoot
대신 사용할 클라우드 API가 있습니다. https://ocr.space/OCRAPI – Bart