├── .gitattributes ├── .gitignore ├── .vs ├── ProjectSettings.json └── slnx.sqlite ├── ImageScanOCR.sln ├── ImageScanOCR ├── App.xaml ├── App.xaml.cs ├── Assets │ ├── BadgeLogo.scale-100.png │ ├── BadgeLogo.scale-125.png │ ├── BadgeLogo.scale-150.png │ ├── BadgeLogo.scale-200.png │ ├── BadgeLogo.scale-400.png │ ├── LargeTile.scale-100.png │ ├── LargeTile.scale-125.png │ ├── LargeTile.scale-150.png │ ├── LargeTile.scale-200.png │ ├── LargeTile.scale-400.png │ ├── LockScreenLogo.scale-200.png │ ├── SplashScreen.scale-100.png │ ├── SplashScreen.scale-125.png │ ├── SplashScreen.scale-150.png │ ├── SplashScreen.scale-200.png │ ├── SplashScreen.scale-400.png │ ├── Square150x150Logo.scale-100.png │ ├── Square150x150Logo.scale-125.png │ ├── Square150x150Logo.scale-150.png │ ├── Square150x150Logo.scale-200.png │ ├── Square150x150Logo.scale-400.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-16.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-24.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-256.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-32.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-48.png │ ├── Square44x44Logo.altform-unplated_targetsize-16.png │ ├── Square44x44Logo.altform-unplated_targetsize-256.png │ ├── Square44x44Logo.altform-unplated_targetsize-32.png │ ├── Square44x44Logo.altform-unplated_targetsize-48.png │ ├── Square44x44Logo.scale-100.png │ ├── Square44x44Logo.scale-125.png │ ├── Square44x44Logo.scale-150.png │ ├── Square44x44Logo.scale-200.png │ ├── Square44x44Logo.scale-400.png │ ├── Square44x44Logo.targetsize-16.png │ ├── Square44x44Logo.targetsize-24.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── Square44x44Logo.targetsize-256.png │ ├── Square44x44Logo.targetsize-32.png │ ├── Square44x44Logo.targetsize-48.png │ ├── Square71x71Logo.scale-100.png │ ├── Square71x71Logo.scale-125.png │ ├── Square71x71Logo.scale-150.png │ ├── Square71x71Logo.scale-200.png │ ├── Square71x71Logo.scale-400.png │ ├── StoreLogo.png │ ├── StoreLogo.scale-100.png │ ├── StoreLogo.scale-125.png │ ├── StoreLogo.scale-150.png │ ├── StoreLogo.scale-200.png │ ├── StoreLogo.scale-400.png │ ├── Wide310x150Logo.scale-100.png │ ├── Wide310x150Logo.scale-125.png │ ├── Wide310x150Logo.scale-150.png │ ├── Wide310x150Logo.scale-200.png │ ├── Wide310x150Logo.scale-400.png │ └── ocr_512.png ├── ImageScanOCR.csproj ├── MainPage.xaml ├── MainPage.xaml.cs ├── Package.appxmanifest └── Properties │ ├── AssemblyInfo.cs │ └── Default.rd.xml ├── LICENSE ├── README.md └── doc ├── dummy.pdf ├── microsoft.png ├── ocr_128.png ├── ocr_16.png ├── ocr_24.png ├── ocr_256.png ├── ocr_32.png ├── ocr_512.png ├── ocr_64.png ├── privacy_policy.md ├── screenshot_1.png ├── screenshot_2.png ├── screenshot_3.png ├── screenshot_4.png ├── softpedia.png └── test.png /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd -------------------------------------------------------------------------------- /.vs/ProjectSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "CurrentProjectSetting": null 3 | } -------------------------------------------------------------------------------- /.vs/slnx.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/.vs/slnx.sqlite -------------------------------------------------------------------------------- /ImageScanOCR.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31729.503 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageScanOCR", "ImageScanOCR\ImageScanOCR.csproj", "{3CFFC915-8C27-4124-925C-654114144D55}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|ARM64 = Debug|ARM64 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|ARM = Release|ARM 15 | Release|ARM64 = Release|ARM64 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {3CFFC915-8C27-4124-925C-654114144D55}.Debug|ARM.ActiveCfg = Debug|ARM 21 | {3CFFC915-8C27-4124-925C-654114144D55}.Debug|ARM.Build.0 = Debug|ARM 22 | {3CFFC915-8C27-4124-925C-654114144D55}.Debug|ARM.Deploy.0 = Debug|ARM 23 | {3CFFC915-8C27-4124-925C-654114144D55}.Debug|ARM64.ActiveCfg = Debug|ARM64 24 | {3CFFC915-8C27-4124-925C-654114144D55}.Debug|ARM64.Build.0 = Debug|ARM64 25 | {3CFFC915-8C27-4124-925C-654114144D55}.Debug|ARM64.Deploy.0 = Debug|ARM64 26 | {3CFFC915-8C27-4124-925C-654114144D55}.Debug|x64.ActiveCfg = Debug|x64 27 | {3CFFC915-8C27-4124-925C-654114144D55}.Debug|x64.Build.0 = Debug|x64 28 | {3CFFC915-8C27-4124-925C-654114144D55}.Debug|x64.Deploy.0 = Debug|x64 29 | {3CFFC915-8C27-4124-925C-654114144D55}.Debug|x86.ActiveCfg = Debug|x86 30 | {3CFFC915-8C27-4124-925C-654114144D55}.Debug|x86.Build.0 = Debug|x86 31 | {3CFFC915-8C27-4124-925C-654114144D55}.Debug|x86.Deploy.0 = Debug|x86 32 | {3CFFC915-8C27-4124-925C-654114144D55}.Release|ARM.ActiveCfg = Release|ARM 33 | {3CFFC915-8C27-4124-925C-654114144D55}.Release|ARM.Build.0 = Release|ARM 34 | {3CFFC915-8C27-4124-925C-654114144D55}.Release|ARM.Deploy.0 = Release|ARM 35 | {3CFFC915-8C27-4124-925C-654114144D55}.Release|ARM64.ActiveCfg = Release|ARM64 36 | {3CFFC915-8C27-4124-925C-654114144D55}.Release|ARM64.Build.0 = Release|ARM64 37 | {3CFFC915-8C27-4124-925C-654114144D55}.Release|ARM64.Deploy.0 = Release|ARM64 38 | {3CFFC915-8C27-4124-925C-654114144D55}.Release|x64.ActiveCfg = Release|x64 39 | {3CFFC915-8C27-4124-925C-654114144D55}.Release|x64.Build.0 = Release|x64 40 | {3CFFC915-8C27-4124-925C-654114144D55}.Release|x64.Deploy.0 = Release|x64 41 | {3CFFC915-8C27-4124-925C-654114144D55}.Release|x86.ActiveCfg = Release|x86 42 | {3CFFC915-8C27-4124-925C-654114144D55}.Release|x86.Build.0 = Release|x86 43 | {3CFFC915-8C27-4124-925C-654114144D55}.Release|x86.Deploy.0 = Release|x86 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | GlobalSection(ExtensibilityGlobals) = postSolution 49 | SolutionGuid = {C450B880-C5E7-4A57-8FEE-20649E26397E} 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /ImageScanOCR/App.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ImageScanOCR/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices.WindowsRuntime; 6 | using Windows.ApplicationModel; 7 | using Windows.ApplicationModel.Activation; 8 | using Windows.Foundation; 9 | using Windows.Foundation.Collections; 10 | using Windows.UI.Xaml; 11 | using Windows.UI.Xaml.Controls; 12 | using Windows.UI.Xaml.Controls.Primitives; 13 | using Windows.UI.Xaml.Data; 14 | using Windows.UI.Xaml.Input; 15 | using Windows.UI.Xaml.Media; 16 | using Windows.UI.Xaml.Navigation; 17 | 18 | namespace ImageScanOCR 19 | { 20 | /// 21 | /// 기본 애플리케이션 클래스를 보완하는 애플리케이션별 동작을 제공합니다. 22 | /// 23 | sealed partial class App : Application 24 | { 25 | /// 26 | /// Singleton 애플리케이션 개체를 초기화합니다. 이것은 실행되는 작성 코드의 첫 번째 27 | /// 줄이며 따라서 main() 또는 WinMain()과 논리적으로 동일합니다. 28 | /// 29 | public App() 30 | { 31 | this.InitializeComponent(); 32 | this.Suspending += OnSuspending; 33 | } 34 | 35 | /// 36 | /// 최종 사용자가 애플리케이션을 정상적으로 시작할 때 호출됩니다. 다른 진입점은 37 | /// 특정 파일을 여는 등 애플리케이션을 시작할 때 38 | /// 39 | /// 시작 요청 및 프로세스에 대한 정보입니다. 40 | protected override void OnLaunched(LaunchActivatedEventArgs e) 41 | { 42 | Frame rootFrame = Window.Current.Content as Frame; 43 | 44 | // 창에 콘텐츠가 이미 있는 경우 앱 초기화를 반복하지 말고, 45 | // 창이 활성화되어 있는지 확인하십시오. 46 | if (rootFrame == null) 47 | { 48 | // 탐색 컨텍스트로 사용할 프레임을 만들고 첫 페이지로 이동합니다. 49 | rootFrame = new Frame(); 50 | 51 | rootFrame.NavigationFailed += OnNavigationFailed; 52 | 53 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) 54 | { 55 | //TODO: 이전에 일시 중지된 애플리케이션에서 상태를 로드합니다. 56 | } 57 | 58 | // 현재 창에 프레임 넣기 59 | Window.Current.Content = rootFrame; 60 | } 61 | 62 | if (e.PrelaunchActivated == false) 63 | { 64 | if (rootFrame.Content == null) 65 | { 66 | // 탐색 스택이 복원되지 않으면 첫 번째 페이지로 돌아가고 67 | // 필요한 정보를 탐색 매개 변수로 전달하여 새 페이지를 68 | // 구성합니다. 69 | rootFrame.Navigate(typeof(MainPage), e.Arguments); 70 | } 71 | // 현재 창이 활성 창인지 확인 72 | Window.Current.Activate(); 73 | } 74 | } 75 | 76 | /// 77 | /// 특정 페이지 탐색에 실패한 경우 호출됨 78 | /// 79 | /// 탐색에 실패한 프레임 80 | /// 탐색 실패에 대한 정보 81 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e) 82 | { 83 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName); 84 | } 85 | 86 | /// 87 | /// 애플리케이션 실행이 일시 중단된 경우 호출됩니다. 애플리케이션이 종료될지 88 | /// 또는 메모리 콘텐츠를 변경하지 않고 다시 시작할지 여부를 결정하지 않은 채 89 | /// 응용 프로그램 상태가 저장됩니다. 90 | /// 91 | /// 일시 중단 요청의 소스입니다. 92 | /// 일시 중단 요청에 대한 세부 정보입니다. 93 | private void OnSuspending(object sender, SuspendingEventArgs e) 94 | { 95 | var deferral = e.SuspendingOperation.GetDeferral(); 96 | //TODO: 애플리케이션 상태를 저장하고 백그라운드 작업을 모두 중지합니다. 97 | deferral.Complete(); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /ImageScanOCR/Assets/BadgeLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/BadgeLogo.scale-100.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/BadgeLogo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/BadgeLogo.scale-125.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/BadgeLogo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/BadgeLogo.scale-150.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/BadgeLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/BadgeLogo.scale-200.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/BadgeLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/BadgeLogo.scale-400.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/LargeTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/LargeTile.scale-100.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/LargeTile.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/LargeTile.scale-125.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/LargeTile.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/LargeTile.scale-150.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/LargeTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/LargeTile.scale-200.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/LargeTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/LargeTile.scale-400.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/SplashScreen.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/SplashScreen.scale-100.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/SplashScreen.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/SplashScreen.scale-125.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/SplashScreen.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/SplashScreen.scale-150.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/SplashScreen.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/SplashScreen.scale-400.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square150x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square150x150Logo.scale-100.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square150x150Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square150x150Logo.scale-125.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square150x150Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square150x150Logo.scale-150.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square150x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square150x150Logo.scale-400.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.altform-unplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.altform-unplated_targetsize-16.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.altform-unplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.altform-unplated_targetsize-256.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.altform-unplated_targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.altform-unplated_targetsize-32.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.altform-unplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.altform-unplated_targetsize-48.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.scale-100.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.scale-125.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.scale-150.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.scale-400.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.targetsize-16.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.targetsize-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.targetsize-24.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.targetsize-256.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.targetsize-32.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square44x44Logo.targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square44x44Logo.targetsize-48.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square71x71Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square71x71Logo.scale-100.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square71x71Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square71x71Logo.scale-125.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square71x71Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square71x71Logo.scale-150.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square71x71Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square71x71Logo.scale-200.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Square71x71Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Square71x71Logo.scale-400.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/StoreLogo.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/StoreLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/StoreLogo.scale-100.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/StoreLogo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/StoreLogo.scale-125.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/StoreLogo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/StoreLogo.scale-150.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/StoreLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/StoreLogo.scale-200.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/StoreLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/StoreLogo.scale-400.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Wide310x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Wide310x150Logo.scale-100.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Wide310x150Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Wide310x150Logo.scale-125.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Wide310x150Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Wide310x150Logo.scale-150.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/Wide310x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/Wide310x150Logo.scale-400.png -------------------------------------------------------------------------------- /ImageScanOCR/Assets/ocr_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/ImageScanOCR/Assets/ocr_512.png -------------------------------------------------------------------------------- /ImageScanOCR/ImageScanOCR.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x86 7 | {3CFFC915-8C27-4124-925C-654114144D55} 8 | AppContainerExe 9 | Properties 10 | ImageScanOCR 11 | ImageScanOCR 12 | en-US 13 | UAP 14 | 10.0.19041.0 15 | 10.0.17763.0 16 | 14 17 | 512 18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 19 | true 20 | false 21 | False 22 | False 23 | True 24 | Always 25 | x86|x64|arm|arm64 26 | True 27 | 0 28 | 29 | 30 | true 31 | bin\x86\Debug\ 32 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 33 | ;2008 34 | full 35 | x86 36 | false 37 | prompt 38 | true 39 | 40 | 41 | bin\x86\Release\ 42 | TRACE;NETFX_CORE;WINDOWS_UWP 43 | true 44 | ;2008 45 | pdbonly 46 | x86 47 | false 48 | prompt 49 | true 50 | true 51 | 52 | 53 | true 54 | bin\ARM\Debug\ 55 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 56 | ;2008 57 | full 58 | ARM 59 | false 60 | prompt 61 | true 62 | 63 | 64 | bin\ARM\Release\ 65 | TRACE;NETFX_CORE;WINDOWS_UWP 66 | true 67 | ;2008 68 | pdbonly 69 | ARM 70 | false 71 | prompt 72 | true 73 | true 74 | 75 | 76 | true 77 | bin\ARM64\Debug\ 78 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 79 | ;2008 80 | full 81 | ARM64 82 | false 83 | prompt 84 | true 85 | true 86 | 87 | 88 | bin\ARM64\Release\ 89 | TRACE;NETFX_CORE;WINDOWS_UWP 90 | true 91 | ;2008 92 | pdbonly 93 | ARM64 94 | false 95 | prompt 96 | true 97 | true 98 | 99 | 100 | true 101 | bin\x64\Debug\ 102 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 103 | ;2008 104 | full 105 | x64 106 | false 107 | prompt 108 | true 109 | 110 | 111 | bin\x64\Release\ 112 | TRACE;NETFX_CORE;WINDOWS_UWP 113 | true 114 | ;2008 115 | pdbonly 116 | x64 117 | false 118 | prompt 119 | true 120 | true 121 | 122 | 123 | PackageReference 124 | 125 | 126 | 127 | App.xaml 128 | 129 | 130 | MainPage.xaml 131 | 132 | 133 | 134 | 135 | 136 | Designer 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | MSBuild:Compile 202 | Designer 203 | 204 | 205 | MSBuild:Compile 206 | Designer 207 | 208 | 209 | 210 | 211 | 6.2.14 212 | 213 | 214 | 7.1.2 215 | 216 | 217 | 2.8.1 218 | 219 | 220 | 221 | 14.0 222 | 223 | 224 | 231 | -------------------------------------------------------------------------------- /ImageScanOCR/MainPage.xaml: -------------------------------------------------------------------------------- 1 |  13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 63 | 64 | 65 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 148 | 149 | 155 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 172 | 173 | 174 | 175 | Add language pack from the 176 | Window Settings Link 177 | and restart program 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | -------------------------------------------------------------------------------- /ImageScanOCR/MainPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Graphics.Canvas; 2 | using Microsoft.Graphics.Canvas.UI.Composition; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.ObjectModel; 6 | using System.Collections.Specialized; 7 | using System.Diagnostics; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Numerics; 11 | using System.Text.RegularExpressions; 12 | using System.Threading; 13 | using System.Threading.Tasks; 14 | using System.Xml.Linq; 15 | using Windows.ApplicationModel.Core; 16 | using Windows.ApplicationModel.DataTransfer; 17 | using Windows.Data.Pdf; 18 | using Windows.Foundation; 19 | using Windows.Globalization; 20 | using Windows.Graphics; 21 | using Windows.Graphics.Capture; 22 | using Windows.Graphics.DirectX; 23 | using Windows.Graphics.Imaging; 24 | using Windows.Media.Ocr; 25 | using Windows.Storage; 26 | using Windows.Storage.AccessCache; 27 | using Windows.Storage.FileProperties; 28 | using Windows.Storage.Pickers; 29 | using Windows.Storage.Streams; 30 | using Windows.System; 31 | using Windows.UI; 32 | using Windows.UI.Composition; 33 | using Windows.UI.Core; 34 | using Windows.UI.Input; 35 | using Windows.UI.ViewManagement; 36 | using Windows.UI.Xaml; 37 | using Windows.UI.Xaml.Controls; 38 | using Windows.UI.Xaml.Hosting; 39 | using Windows.UI.Xaml.Input; 40 | using Windows.UI.Xaml.Media.Imaging; 41 | using muxc = Microsoft.UI.Xaml.Controls; 42 | 43 | namespace ImageScanOCR { 44 | /// 45 | /// OCR main page 46 | /// explorer image from left side panel 47 | /// select image to display image and process ocr to display text in right panel 48 | /// 49 | public sealed partial class MainPage : Page { 50 | //observable 51 | ObservableCollection Breadcrumbs = new ObservableCollection(); 52 | ObservableCollection ExplorerList = new ObservableCollection(); 53 | ObservableCollection LanguageList = new ObservableCollection(); 54 | ObservableCollection ImageList = new ObservableCollection(); 55 | 56 | // 57 | Language SelectedLang = null; 58 | SoftwareBitmap CurrentBitmap = null; 59 | List CurrentOcrResult = new List() { }; 60 | List PrevOcrResult = new List() { }; 61 | string PrevOcrTextMode = ""; 62 | ApplicationDataContainer LocalSettings = SettingHandler.GetSetting(); 63 | CancellationTokenSource TokenSource = new CancellationTokenSource(); 64 | string CurrentProcessedItemName = "New Document"; 65 | private bool IsCropped = false; 66 | private BoxCoordinates cropBoxCoordinates; 67 | CoreCursor cursorBeforePointerEntered = Window.Current.CoreWindow.PointerCursor; 68 | private bool textFieldFocused = false; 69 | 70 | // Capture API objects. 71 | private SizeInt32 _lastSize; 72 | private GraphicsCaptureItem _item; 73 | private Direct3D11CaptureFramePool _framePool; 74 | private GraphicsCaptureSession _session; 75 | private CanvasDevice _canvasDevice; 76 | private CompositionGraphicsDevice _compositionGraphicsDevice; 77 | private Compositor _compositor; 78 | private CompositionDrawingSurface _surface; 79 | private CanvasBitmap _currentFrame; 80 | private DispatcherTimer _captureDispatcherTimer = new DispatcherTimer(); 81 | private DateTime _lastOcrRuntime = DateTime.Now; 82 | 83 | public MainPage() { 84 | Debug.WriteLine("Start=============================="); 85 | //TaskScheduler.UnobservedTaskException += OnUnobservedException; 86 | this.InitializeComponent(); 87 | InitTitleBar(); 88 | InitFolderViewList(); 89 | InitLanguageList(); 90 | InitTooltip(); 91 | InitFolderRefresh(); 92 | SetupCapture(); 93 | } 94 | 95 | 96 | 97 | 98 | private static void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e) { 99 | // Occurs when an exception is not handled on a background thread. 100 | // ie. A task is fired and forgotten Task.Run(() => {...}) 101 | // suppress and handle it manually. 102 | Debug.WriteLine("OnUnobservedException=============================="); 103 | Debug.WriteLine(e.Exception.ToString()); 104 | e.SetObserved(); 105 | } 106 | 107 | 108 | 109 | 110 | private void InitTitleBar() { 111 | var titleBar = ApplicationView.GetForCurrentView().TitleBar; 112 | titleBar.ButtonBackgroundColor = Colors.Transparent; 113 | titleBar.ButtonInactiveBackgroundColor = Colors.Transparent; 114 | 115 | // Hide default title bar. 116 | var coreTitleBar = CoreApplication.GetCurrentView().TitleBar; 117 | coreTitleBar.ExtendViewIntoTitleBar = true; 118 | 119 | // Set XAML element as a draggable region. 120 | //Window.Current.SetTitleBar(AppTitleBar); 121 | } 122 | 123 | 124 | 125 | private void InitTooltip() { 126 | String isTooltipShowed = LocalSettings.Values["IsTooltipShowed"] as string; 127 | if (isTooltipShowed == "false") { 128 | MoreLanguageTip.IsOpen = true; 129 | LocalSettings.Values["IsTooltipShowed"] = "true"; 130 | } 131 | } 132 | 133 | 134 | 135 | 136 | 137 | //language setting============================================================================================================================ 138 | private void InitLanguageList() { 139 | LanguageList = new ObservableCollection(OcrProcessor.GetOcrLangList()); 140 | SelectLanguageFromSetting(); 141 | } 142 | 143 | 144 | private void SelectLanguageFromSetting() { 145 | String settingLang = LocalSettings.Values["Language"] as string; 146 | 147 | //set matched lang as selected item 148 | //if no saved lang use first item 149 | for (int i = 0; i < LanguageList.Count; i++) { 150 | if (LanguageList[i].LanguageTag == settingLang || settingLang == "") { 151 | LangCombo.SelectedIndex = i; 152 | break; 153 | } 154 | } 155 | } 156 | 157 | private void LangCombo_SelectionChanged(object sender, SelectionChangedEventArgs e) { 158 | //save language when changed and reprocess image 159 | SelectedLang = e.AddedItems[0] as Language; 160 | LocalSettings.Values["Language"] = SelectedLang.LanguageTag; 161 | ProcessImage(CurrentBitmap, false, false); 162 | } 163 | 164 | private async void AddLanguage_Click(object sender, RoutedEventArgs e) { 165 | await Launcher.LaunchUriAsync(new Uri("ms-settings:regionlanguage-adddisplaylanguage")); 166 | } 167 | 168 | 169 | 170 | 171 | 172 | //folder explorer============================================================================================================================ 173 | 174 | private async void InitFolderViewList() { 175 | Breadcrumbs.CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) => UpdateExplorerListView(); 176 | 177 | try { 178 | //open recent picked folder 179 | string token = (string)LocalSettings.Values["RecentAccessFolderToken"]; 180 | if (token != "" && StorageApplicationPermissions.FutureAccessList.ContainsItem(token)) { 181 | var folder = await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(token); 182 | Breadcrumbs.Add(new ExplorerItem(folder)); 183 | } else { 184 | // if no recent picked folder, show picture library 185 | Breadcrumbs.Add(new ExplorerItem(KnownFolders.PicturesLibrary)); 186 | } 187 | } catch (FileNotFoundException) { 188 | Debug.WriteLine("File not found"); 189 | } 190 | } 191 | 192 | 193 | 194 | private void InitFolderRefresh() { 195 | var dispatcherTimer = new DispatcherTimer(); 196 | dispatcherTimer.Tick += (object source, object e) => RefreshFileList(); 197 | dispatcherTimer.Interval = new TimeSpan(0, 0, 5); 198 | dispatcherTimer.Start(); 199 | } 200 | 201 | 202 | private async void RefreshFileList() { 203 | if (Breadcrumbs.Any()) { 204 | List recentFileList = await Breadcrumbs.Last().GetChildItemList(); 205 | 206 | //remove deleted file from dir 207 | for (int i = 0; i < ExplorerList.Count(); i++) { 208 | if (!recentFileList.Any(item => item.Name == ExplorerList[i].Name)) { 209 | ExplorerList.RemoveAt(i); 210 | i--; 211 | } 212 | } 213 | 214 | //append new add file from dir 215 | for (int i = 0; i < recentFileList.Count(); i++) { 216 | if (ExplorerList.Count <= i || recentFileList[i].Name != ExplorerList[i].Name) { 217 | ExplorerList.Insert(i, recentFileList[i]); 218 | } 219 | } 220 | } 221 | } 222 | 223 | 224 | 225 | 226 | private void FolderBreadcrumbBar_ItemClicked(muxc.BreadcrumbBar sender, muxc.BreadcrumbBarItemClickedEventArgs clickedItem) { 227 | // Don't process last index (current location), right most one 228 | if (clickedItem.Index == Breadcrumbs.Count - 1) { 229 | return; 230 | } 231 | 232 | // Remove breadcrumbs at the end until 233 | // you get to the one that was clicked. 234 | while (Breadcrumbs.Count > clickedItem.Index + 1) { 235 | Breadcrumbs.RemoveAt(Breadcrumbs.Count - 1); 236 | } 237 | } 238 | 239 | 240 | //if is folder, open it and update breadcrum/exploer list 241 | //if file open image and process 242 | private async void FolderListView_SelectionChangedAsync(object sender, SelectionChangedEventArgs e) { 243 | 244 | var selectedItem = this.FolderListView.SelectedItem as ExplorerItem; 245 | if (selectedItem == null) { 246 | return; 247 | }else if (selectedItem.Label == "folder" || selectedItem.Label == "pdf") { 248 | Breadcrumbs.Add(selectedItem); 249 | } else if (selectedItem.Label == "file" || selectedItem.Label == "pdfPage") { 250 | CurrentProcessedItemName = selectedItem.Name; 251 | CurrentBitmap = await selectedItem.GetBitmapImage(); 252 | ProcessImage(CurrentBitmap); 253 | } 254 | } 255 | 256 | 257 | //open folder and reset 258 | private async void OpenFolder_Click(object sender, RoutedEventArgs e) { 259 | var folderPicker = new FolderPicker(); 260 | folderPicker.SuggestedStartLocation = PickerLocationId.Downloads; 261 | folderPicker.FileTypeFilter.Add("*"); 262 | StorageFolder pickedFolder = await folderPicker.PickSingleFolderAsync(); 263 | if (pickedFolder != null) { 264 | // Folder was picked you can now use it 265 | var token = StorageApplicationPermissions.FutureAccessList.Add(pickedFolder); 266 | LocalSettings.Values["RecentAccessFolderToken"] = token; 267 | Breadcrumbs.Clear(); 268 | Breadcrumbs.Add(new ExplorerItem(pickedFolder)); 269 | } 270 | } 271 | 272 | private async void UpdateExplorerListView() { 273 | if (Breadcrumbs.Any()) { 274 | List recentFileList = await Breadcrumbs.Last().GetChildItemList(); 275 | ExplorerList.Clear(); 276 | recentFileList.ForEach(ExplorerList.Add); 277 | } 278 | } 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | //image process============================================================================================================================================= 287 | private async void Rotate_Click(object sender, RoutedEventArgs e) { 288 | CurrentBitmap = await ImageProcessor.SoftwareBitmapRotate(CurrentBitmap); 289 | ProcessImage(CurrentBitmap); 290 | } 291 | 292 | public async void ProcessImage(SoftwareBitmap imageItem, bool updateDisplayImage = true, bool resetPrevProcess = true) { 293 | if (imageItem == null) { 294 | return; 295 | } 296 | 297 | if (resetPrevProcess) { 298 | resetImageProcess(); 299 | } 300 | 301 | if (updateDisplayImage) { 302 | DisplayImage(imageItem); 303 | showSingleImageBox(); 304 | } 305 | if (IsCropped) { 306 | (uint x, uint y, uint w, uint h) = cropBoxCoordinates.GetRatioXYWH(imageItem.PixelWidth, imageItem.PixelHeight); 307 | if (w > 1 && h > 1) { //if too small crop skip 308 | imageItem = await ImageProcessor.GetCroppedImage(imageItem, x, y, w, h); 309 | } 310 | } 311 | 312 | 313 | CurrentOcrResult = await OcrProcessor.GetText(imageItem, SelectedLang); 314 | DisplayText(); 315 | } 316 | 317 | public async void DisplayImage(SoftwareBitmap imageItem) { 318 | PreviewImage.Source = await ImageProcessor.getImageSource(imageItem); 319 | } 320 | 321 | private void showSingleImageBox() { 322 | ImageSingleBox.Visibility = Visibility.Visible; 323 | PreviewImage.Visibility = Visibility.Visible; 324 | MyCanvas.Visibility = Visibility.Visible; 325 | } 326 | private void showScrollImageBox() { 327 | ImageListView.Visibility = Visibility.Visible; 328 | } 329 | private void showCaptureBox() { 330 | ImageSingleBox.Visibility = Visibility.Visible; 331 | PreviewImage.Visibility = Visibility.Visible; 332 | CaptureBox.Visibility = Visibility.Visible; 333 | MyCanvas.Visibility = Visibility.Visible; 334 | } 335 | private void resetImageProcess() { 336 | //image reset 337 | ImageSingleBox.Visibility = Visibility.Collapsed; 338 | PreviewImage.Visibility = Visibility.Collapsed; 339 | MyCanvas.Visibility = Visibility.Collapsed; 340 | CropBox.Visibility = Visibility.Collapsed; 341 | CurrentOcrResult.Clear(); 342 | IsCropped = false; 343 | cropBoxCoordinates = null; 344 | 345 | //batch reset 346 | ImageListView.Visibility = Visibility.Collapsed; 347 | ImageList.Clear(); 348 | CancelBatchProcess(); 349 | ProgressItem.IsActive = false; 350 | ShowBatchButton(); 351 | 352 | //capture reset 353 | CaptureBox.Visibility = Visibility.Collapsed; 354 | ShowCaptureButton(); 355 | StopCapture(); 356 | } 357 | 358 | private void ScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e) { 359 | var scrollViewer = ((ScrollViewer)sender); 360 | ImageSingleGrid.Width = scrollViewer.ActualWidth; 361 | ImageSingleGrid.Height = scrollViewer.ActualHeight; 362 | } 363 | 364 | 365 | 366 | //Batch ============================================================================================================================ 367 | 368 | private async void BatchProcess_Click(object sender, RoutedEventArgs e) { 369 | resetImageProcess(); 370 | showScrollImageBox(); 371 | ShowCancelBatchButton(); 372 | ProgressItem.IsActive = true; 373 | 374 | await ProcessBatch(); 375 | 376 | ShowBatchButton(); 377 | DisplayText(); 378 | ProgressItem.IsActive = false; 379 | } 380 | 381 | private void ShowBatchButton() { 382 | BatchProcess.Visibility = Visibility.Visible; 383 | CancelBatch.Visibility = Visibility.Collapsed; 384 | } 385 | private void ShowCancelBatchButton() { 386 | BatchProcess.Visibility = Visibility.Collapsed; 387 | CancelBatch.Visibility = Visibility.Visible; 388 | } 389 | 390 | 391 | private async Task ProcessBatch() { 392 | TokenSource = new CancellationTokenSource(); 393 | var token = TokenSource.Token; 394 | 395 | foreach (ExplorerItem item in ExplorerList) { 396 | if (token.IsCancellationRequested) { 397 | break; 398 | } 399 | 400 | if (item.Label == "pdfPage" || item.Label == "file") { 401 | CurrentProcessedItemName = ((ExplorerItem)Breadcrumbs.Last()).Name; 402 | SoftwareBitmap bitmapImage = await item.GetBitmapImage(); 403 | 404 | List textList = await OcrProcessor.GetText(bitmapImage, SelectedLang); 405 | textList.Add(""); //add empty line to separate result 406 | CurrentOcrResult.AddRange(textList); 407 | 408 | //display update 409 | ImageList.Add(await ImageProcessor.getImageSource(bitmapImage)); 410 | DisplayText(); 411 | } 412 | } 413 | } 414 | 415 | 416 | private void CancelBatch_Click(object sender, RoutedEventArgs e) { 417 | CancelBatchProcess(); 418 | } 419 | 420 | private void CancelBatchProcess() { 421 | if (TokenSource != null) { 422 | TokenSource.Cancel(); 423 | } 424 | } 425 | 426 | 427 | 428 | 429 | 430 | //text process ===================================================================================================================================== 431 | 432 | 433 | private void SaveFile_Click(object sender, RoutedEventArgs e) { 434 | TextProcessor.SaveTextFIle(CurrentProcessedItemName, TextField.Text); 435 | } 436 | 437 | private void CopyAll_Click(object sender, RoutedEventArgs e) { 438 | TextProcessor.CopyTextToClipboard(TextField.Text); 439 | } 440 | 441 | private void WrapText_Click(object sender, RoutedEventArgs e) { 442 | ChangeTextWrapSetting(); 443 | DisplayText(); 444 | } 445 | 446 | private void ChangeTextWrapSetting() { 447 | string currentSelectedItem = (string)LocalSettings.Values["WrapText"]; 448 | LocalSettings.Values["WrapText"] = TextProcessor.GetNextTextMode(currentSelectedItem); 449 | } 450 | private void DisplayText() { 451 | string currentMode = LocalSettings.Values["WrapText"] as string; 452 | 453 | //if ocr text result is not changed, skip 454 | if (PrevOcrResult.SequenceEqual(CurrentOcrResult) && PrevOcrTextMode == currentMode) { 455 | return; 456 | } 457 | 458 | TextField.Text = TextProcessor.GetWrapText(CurrentOcrResult, currentMode); 459 | 460 | PrevOcrResult = new List(CurrentOcrResult.ToArray()); 461 | PrevOcrTextMode = currentMode; 462 | } 463 | 464 | 465 | 466 | //drag drop ===================================================================================================================================== 467 | 468 | private void Grid_DragOver(object sender, DragEventArgs e) { 469 | e.AcceptedOperation = DataPackageOperation.Copy; 470 | // To display the data which is dragged 471 | e.DragUIOverride.Caption = "drop here to view image"; 472 | e.DragUIOverride.IsGlyphVisible = true; 473 | e.DragUIOverride.IsContentVisible = true; 474 | e.DragUIOverride.IsCaptionVisible = true; 475 | } 476 | 477 | private async void Grid_Drop(object sender, DragEventArgs e) { 478 | if (e.DataView.Contains(StandardDataFormats.StorageItems)) { 479 | var items = await e.DataView.GetStorageItemsAsync(); 480 | if (items.Any()) { 481 | var storageFile = items[0] as StorageFile; 482 | 483 | if (new List() { ".jpeg", ".jpg", ".png", ".gif", ".tiff", ".bmp" }.Contains(storageFile.FileType.ToLower())) { 484 | ExplorerItem item = new ExplorerItem(storageFile); 485 | CurrentProcessedItemName = item.Name; 486 | CurrentBitmap = await item.GetBitmapImage(); 487 | ProcessImage(CurrentBitmap); 488 | } 489 | } 490 | } 491 | } 492 | 493 | 494 | 495 | /// canvas crop======================================================= 496 | 497 | 498 | 499 | private void PreviewImage_SizeChanged(object sender, SizeChangedEventArgs e) { 500 | IsCropped = false; 501 | cropBoxCoordinates = null; 502 | CropBox.Visibility = Visibility.Collapsed; 503 | MyCanvas.Width = ((Image)sender).ActualWidth; 504 | MyCanvas.Height = ((Image)sender).ActualHeight; 505 | } 506 | 507 | private void Canvas_MouseEntered(object sender, PointerRoutedEventArgs e) { 508 | Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Cross, 0); 509 | } 510 | private void Canvas_MouseDown(object sender, PointerRoutedEventArgs e) { 511 | (int X, int Y, bool IsLeftButtonPressed) = GetPointerStatus(sender, e); 512 | 513 | if (IsLeftButtonPressed) { 514 | UpdateCropBox(X, Y, true); 515 | } 516 | e.Handled = true; 517 | } 518 | private void Canvas_MouseMove(object sender, PointerRoutedEventArgs e) { 519 | (int X, int Y, bool IsLeftButtonPressed) = GetPointerStatus(sender, e); 520 | UpdateCropBox(X, Y); 521 | e.Handled = true; 522 | } 523 | 524 | private void Canvas_MouseUp(object sender, PointerRoutedEventArgs e) { 525 | (int X, int Y, bool IsLeftButtonPressed) = GetPointerStatus(sender, e); 526 | 527 | if (!IsLeftButtonPressed) { 528 | ProcessCanvas(X, Y); 529 | } 530 | // Prevent most handlers along the event route from handling the same event again. 531 | e.Handled = true; 532 | 533 | } 534 | 535 | private void Canvas_MouseExited(object sender, PointerRoutedEventArgs e) { 536 | (int X, int Y, bool IsLeftButtonPressed) = GetPointerStatus(sender, e); 537 | ProcessCanvas(X, Y); 538 | Window.Current.CoreWindow.PointerCursor = cursorBeforePointerEntered; 539 | e.Handled = true; 540 | } 541 | 542 | 543 | private void ProcessCanvas(int X, int Y) { 544 | if (IsCropped || cropBoxCoordinates == null) { 545 | return; 546 | } 547 | IsCropped = true; 548 | UpdateCropBox(X, Y); 549 | ProcessImage(CurrentBitmap, false, false); 550 | } 551 | 552 | 553 | private (int, int, bool) GetPointerStatus(object sender, PointerRoutedEventArgs e) { 554 | //return X, Y, IsLeftButtonPressed 555 | PointerPoint ptrPt = e.GetCurrentPoint((UIElement)sender); 556 | return ((int)ptrPt.Position.X, (int)ptrPt.Position.Y, ptrPt.Properties.IsLeftButtonPressed); 557 | } 558 | 559 | private void UpdateCropBox(int X, int Y, bool Reset = false) { 560 | if (Reset) { 561 | IsCropped = false; 562 | cropBoxCoordinates = new BoxCoordinates(X, Y, (int)MyCanvas.Width, (int)MyCanvas.Height); 563 | } 564 | if (IsCropped == true || cropBoxCoordinates == null) { 565 | return; 566 | } 567 | 568 | cropBoxCoordinates.UpdateCoordinates(X, Y); 569 | 570 | CropBox.Translation = new Vector3() { 571 | X = cropBoxCoordinates.X, 572 | Y = cropBoxCoordinates.Y, 573 | Z = 0 574 | }; 575 | CropBox.Width = cropBoxCoordinates.W; 576 | CropBox.Height = cropBoxCoordinates.H; 577 | CropBox.Visibility = Visibility.Visible; 578 | } 579 | 580 | 581 | 582 | 583 | //Screen capture====================================================================================== 584 | 585 | private async void Capture_Click(object sender, RoutedEventArgs e) { 586 | resetImageProcess(); 587 | ShowCancelCaptureButton(); 588 | showCaptureBox(); 589 | await StartCaptureAsync(); 590 | } 591 | 592 | private void CancelCapture_Click(object sender, RoutedEventArgs e) { 593 | ShowCaptureButton(); 594 | StopCapture(); 595 | } 596 | 597 | private void ShowCaptureButton() { 598 | Capture.Visibility = Visibility.Visible; 599 | CancelCapture.Visibility = Visibility.Collapsed; 600 | } 601 | private void ShowCancelCaptureButton() { 602 | Capture.Visibility = Visibility.Collapsed; 603 | CancelCapture.Visibility = Visibility.Visible; 604 | } 605 | 606 | private void SetupCapture() { 607 | if (!GraphicsCaptureSession.IsSupported()) { 608 | // Hide the capture UI if screen capture is not supported. 609 | Capture.Visibility = Visibility.Collapsed; 610 | } 611 | 612 | _canvasDevice = new CanvasDevice(); 613 | 614 | _compositionGraphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice( 615 | Window.Current.Compositor, 616 | _canvasDevice); 617 | 618 | _compositor = Window.Current.Compositor; 619 | 620 | _surface = _compositionGraphicsDevice.CreateDrawingSurface( 621 | new Size(400, 400), 622 | DirectXPixelFormat.B8G8R8A8UIntNormalized, 623 | DirectXAlphaMode.Premultiplied); // This is the only value that currently works with 624 | // the composition APIs. 625 | 626 | 627 | var visual = _compositor.CreateSpriteVisual(); 628 | visual.RelativeSizeAdjustment = Vector2.One; 629 | var brush = _compositor.CreateSurfaceBrush(_surface); 630 | brush.HorizontalAlignmentRatio = 0.5f; 631 | brush.VerticalAlignmentRatio = 0.5f; 632 | brush.Stretch = CompositionStretch.Uniform; 633 | visual.Brush = brush; 634 | ElementCompositionPreview.SetElementChildVisual(CaptureBox, visual); 635 | } 636 | 637 | public async Task StartCaptureAsync() { 638 | // The GraphicsCapturePicker follows the same pattern the 639 | // file pickers do. 640 | var picker = new GraphicsCapturePicker(); 641 | GraphicsCaptureItem item = await picker.PickSingleItemAsync(); 642 | 643 | // The item may be null if the user dismissed the 644 | // control without making a selection or hit Cancel. 645 | if (item != null) { 646 | StartCaptureInternal(item); 647 | } else { 648 | ShowCaptureButton(); 649 | } 650 | } 651 | 652 | 653 | 654 | private void StartCaptureInternal(GraphicsCaptureItem item) { 655 | // Stop the previous capture if we had one. 656 | StopCapture(); 657 | 658 | _item = item; 659 | _lastSize = _item.Size; 660 | 661 | 662 | _framePool = Direct3D11CaptureFramePool.Create( 663 | _canvasDevice, // D3D device 664 | DirectXPixelFormat.B8G8R8A8UIntNormalized, // Pixel format 665 | 2, // Number of frames 666 | _item.Size); // Size of the buffers 667 | 668 | _framePool.FrameArrived += (s, a) => { 669 | using (var frame = _framePool.TryGetNextFrame()) { 670 | ProcessFrame(frame); 671 | } 672 | 673 | }; 674 | 675 | _item.Closed += (s, a) => { 676 | StopCapture(); 677 | }; 678 | 679 | _session = _framePool.CreateCaptureSession(_item); 680 | _session.StartCapture(); 681 | } 682 | 683 | public void StopCapture() { 684 | _session?.Dispose(); 685 | _framePool?.Dispose(); 686 | _item = null; 687 | _session = null; 688 | _framePool = null; 689 | 690 | } 691 | 692 | private void ProcessFrame(Direct3D11CaptureFrame frame) { 693 | // Resize and device-lost leverage the same function on the 694 | // Direct3D11CaptureFramePool. Refactoring it this way avoids 695 | // throwing in the catch block below (device creation could always 696 | // fail) along with ensuring that resize completes successfully and 697 | // isn’t vulnerable to device-lost. 698 | bool needsReset = false; 699 | bool recreateDevice = false; 700 | 701 | if ((frame.ContentSize.Width != _lastSize.Width) || 702 | (frame.ContentSize.Height != _lastSize.Height)) { 703 | needsReset = true; 704 | _lastSize = frame.ContentSize; 705 | } 706 | 707 | try { 708 | // Take the D3D11 surface and draw it into a 709 | // Composition surface. 710 | 711 | // Convert our D3D11 surface into a Win2D object. 712 | CanvasBitmap canvasBitmap = CanvasBitmap.CreateFromDirect3D11Surface( 713 | _canvasDevice, 714 | frame.Surface); 715 | 716 | _currentFrame = canvasBitmap; 717 | 718 | // Helper that handles the drawing for us. 719 | FillSurfaceWithBitmap(canvasBitmap); 720 | OcrOnCapturedImage(canvasBitmap); 721 | } 722 | 723 | 724 | // This is the device-lost convention for Win2D. 725 | catch (Exception e) when (_canvasDevice.IsDeviceLost(e.HResult)) { 726 | // We lost our graphics device. Recreate it and reset 727 | // our Direct3D11CaptureFramePool. 728 | needsReset = true; 729 | recreateDevice = true; 730 | } 731 | 732 | if (needsReset) { 733 | ResetFramePool(frame.ContentSize, recreateDevice); 734 | } 735 | } 736 | 737 | 738 | private void FillSurfaceWithBitmap(CanvasBitmap canvasBitmap) { 739 | CanvasComposition.Resize(_surface, canvasBitmap.Size); 740 | using (var session = CanvasComposition.CreateDrawingSession(_surface)) { 741 | session.Clear(Colors.Transparent); 742 | session.DrawImage(canvasBitmap); 743 | } 744 | } 745 | 746 | 747 | private async void OcrOnCapturedImage(CanvasBitmap canvasBitmap) { 748 | //run ones every 0.7 second, stop if textEdit is focused 749 | if (DateTime.Now.Subtract(_lastOcrRuntime).TotalSeconds > 0.7 && !textFieldFocused) { 750 | _lastOcrRuntime = DateTime.Now; 751 | SoftwareBitmap softwareBitmapImg = await SoftwareBitmap.CreateCopyFromSurfaceAsync(canvasBitmap, BitmapAlphaMode.Premultiplied); 752 | CurrentBitmap = softwareBitmapImg; 753 | DisplayImage(softwareBitmapImg); 754 | ProcessImage(softwareBitmapImg, false, false); 755 | } 756 | } 757 | 758 | 759 | 760 | private void ResetFramePool(SizeInt32 size, bool recreateDevice) { 761 | do { 762 | try { 763 | if (recreateDevice) { 764 | _canvasDevice = new CanvasDevice(); 765 | } 766 | 767 | _framePool.Recreate( 768 | _canvasDevice, 769 | DirectXPixelFormat.B8G8R8A8UIntNormalized, 770 | 2, 771 | size); 772 | } 773 | // This is the device-lost convention for Win2D. 774 | catch (Exception e) when (_canvasDevice.IsDeviceLost(e.HResult)) { 775 | _canvasDevice = null; 776 | recreateDevice = true; 777 | } 778 | } while (_canvasDevice == null); 779 | } 780 | 781 | 782 | private void TextField_GettingFocus(UIElement sender, GettingFocusEventArgs args) { 783 | textFieldFocused = true; 784 | } 785 | 786 | private void TextField_LosingFocus(UIElement sender, LosingFocusEventArgs args) { 787 | textFieldFocused = false; 788 | } 789 | 790 | } 791 | 792 | 793 | 794 | public static class SettingHandler { 795 | public static Dictionary DefaultSetting = new Dictionary(){ 796 | {"Language", ""}, 797 | {"WrapText", "newLine"}, 798 | {"IsTooltipShowed", "false"}, 799 | {"RecentAccessFolderToken", ""} 800 | }; 801 | 802 | public static ApplicationDataContainer GetSetting() { 803 | var localSettings = ApplicationData.Current.LocalSettings; 804 | //if no setting, set default value 805 | foreach (var item in DefaultSetting) { 806 | if (localSettings.Values[item.Key] == null) { 807 | localSettings.Values[item.Key] = item.Value; 808 | } 809 | } 810 | 811 | return localSettings; 812 | } 813 | } 814 | 815 | public static class TextProcessor { 816 | 817 | public static List wrapTextModeList = new List(){ 818 | "newLine","space","sentence" 819 | }; 820 | 821 | public static String GetNextTextMode(String currentSelectedItem) { 822 | int selectedIndex = (wrapTextModeList.IndexOf(currentSelectedItem) + 1) % wrapTextModeList.Count; 823 | string selectedName = wrapTextModeList[selectedIndex]; 824 | return selectedName; 825 | } 826 | 827 | public static String GetWrapText(List currentOcrResult, string currentMode) { 828 | string resultText = ""; 829 | if (currentMode == "newLine") { 830 | resultText = String.Join("\n", currentOcrResult.ToArray()); 831 | } else if (currentMode == "space") { 832 | resultText = String.Join(" ", currentOcrResult.ToArray()); 833 | } else if (currentMode == "sentence") { //split by sentence 834 | resultText = String.Join(" ", currentOcrResult.ToArray()); 835 | string[] sentences = Regex.Split(resultText, @"(?<=[\.!\?])\s+"); 836 | resultText = String.Join("\n", sentences); 837 | } 838 | return resultText; 839 | } 840 | 841 | public static async void SaveTextFIle(String fileName, String text) { 842 | var savePicker = new FileSavePicker(); 843 | savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary; 844 | // Dropdown of file types the user can save the file as 845 | savePicker.FileTypeChoices.Add("Plain Text", new List() { ".txt" }); 846 | // Default file name if the user does not type one in or select a file to replace 847 | savePicker.SuggestedFileName = System.IO.Path.GetFileNameWithoutExtension(fileName); //get current item name without extension 848 | 849 | 850 | StorageFile file = await savePicker.PickSaveFileAsync(); 851 | if (file != null) { 852 | // Prevent updates to the remote version of the file until 853 | // we finish making changes and call CompleteUpdatesAsync. 854 | CachedFileManager.DeferUpdates(file); 855 | 856 | // write to file 857 | await FileIO.WriteTextAsync(file, text); 858 | } 859 | } 860 | 861 | public static void CopyTextToClipboard(String text) { 862 | var dataPackage = new DataPackage(); 863 | dataPackage.SetText(text); 864 | Clipboard.SetContent(dataPackage); 865 | } 866 | 867 | 868 | } 869 | 870 | 871 | public static class ImageProcessor { 872 | 873 | public static async Task LoadImage(StorageFile file, uint maxSize = 2000) { 874 | try { 875 | using (var stream = await file.OpenAsync(FileAccessMode.Read)) { 876 | SoftwareBitmap softwareBitmap; 877 | BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); 878 | ImageProperties imageProperties = await file.Properties.GetImagePropertiesAsync(); 879 | 880 | if (imageProperties.Width < maxSize && imageProperties.Height < maxSize) { 881 | softwareBitmap = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied); 882 | } else { 883 | softwareBitmap = await GetResizedImage(decoder, imageProperties.Orientation, imageProperties.Width, imageProperties.Height, maxSize); 884 | } 885 | 886 | return softwareBitmap; 887 | } 888 | } catch (Exception) { 889 | Debug.WriteLine("Load Image Fail"); 890 | return null; 891 | } 892 | } 893 | 894 | public static async Task GetResizedImage(BitmapDecoder decoder, PhotoOrientation orientation, uint width, uint height, uint maxSize) { 895 | //if rotated, change width height 896 | if (new[] { PhotoOrientation.Rotate270, PhotoOrientation.Rotate90, PhotoOrientation.Transpose, PhotoOrientation.Transverse }.Contains(orientation)) { 897 | (width, height) = (height, width); 898 | } 899 | 900 | float ratio = (float)width / height; 901 | 902 | if (width > maxSize) { 903 | width = maxSize; 904 | height = (uint)(maxSize / ratio); 905 | } 906 | if (height > maxSize) { 907 | width = (uint)(ratio * maxSize); 908 | height = maxSize; 909 | } 910 | 911 | var transform = new BitmapTransform() { 912 | ScaledWidth = width, 913 | ScaledHeight = height, 914 | InterpolationMode = BitmapInterpolationMode.Fant, 915 | }; 916 | 917 | return await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage); 918 | } 919 | 920 | public static async Task GetCroppedImage(SoftwareBitmap softwareBitmap, uint x, uint y, uint w, uint h) { 921 | 922 | using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream()) { 923 | w = (uint)Math.Min(w, softwareBitmap.PixelWidth - x); 924 | h = (uint)Math.Min(h, softwareBitmap.PixelHeight - y); 925 | 926 | BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream); 927 | encoder.SetSoftwareBitmap(softwareBitmap); 928 | encoder.BitmapTransform.Bounds = new BitmapBounds() { 929 | X = x, 930 | Y = y, 931 | Width = w, 932 | Height = h, 933 | }; 934 | 935 | await encoder.FlushAsync(); 936 | BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); 937 | return await decoder.GetSoftwareBitmapAsync(softwareBitmap.BitmapPixelFormat, softwareBitmap.BitmapAlphaMode); 938 | } 939 | } 940 | 941 | public async static Task SoftwareBitmapRotate(SoftwareBitmap softwarebitmap) { 942 | if (softwarebitmap == null) { 943 | return null; 944 | } 945 | //https://github.com/kiwamu25/BarcodeScanner/blob/f5359693019ea957813b364b456bba571f881060/BarcodeScanner/BarcodeScanner/MainPage.xaml.cs 946 | using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream()) { 947 | BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream); 948 | encoder.SetSoftwareBitmap(softwarebitmap); 949 | encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees; 950 | await encoder.FlushAsync(); 951 | BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); 952 | return await decoder.GetSoftwareBitmapAsync(softwarebitmap.BitmapPixelFormat, BitmapAlphaMode.Premultiplied); 953 | } 954 | } 955 | 956 | 957 | 958 | public async static Task getImageSource(SoftwareBitmap softwareBitmap) { 959 | var source = new SoftwareBitmapSource(); 960 | await source.SetBitmapAsync(softwareBitmap); 961 | return source; 962 | } 963 | 964 | 965 | } 966 | 967 | 968 | public static class OcrProcessor { 969 | public static IReadOnlyList GetOcrLangList() { 970 | return OcrEngine.AvailableRecognizerLanguages; 971 | } 972 | public static async Task> GetText(SoftwareBitmap imageItem, Language SelectedLang) { 973 | //check item is null 974 | //check no selectedLang 975 | //check image is too large 976 | if (imageItem == null || 977 | SelectedLang == null || 978 | imageItem.PixelWidth > OcrEngine.MaxImageDimension || 979 | imageItem.PixelHeight > OcrEngine.MaxImageDimension 980 | ) { 981 | return new List { "" }; 982 | } 983 | 984 | 985 | //check ocr image exist 986 | var ocrEngine = OcrEngine.TryCreateFromLanguage(SelectedLang); 987 | if (ocrEngine == null) { 988 | return new List { "" }; 989 | } 990 | 991 | 992 | var ocrResult = await ocrEngine.RecognizeAsync(imageItem); 993 | 994 | 995 | List textList = new List() { }; 996 | foreach (var line in ocrResult.Lines) { 997 | textList.Add(line.Text); 998 | } 999 | return textList; 1000 | } 1001 | 1002 | } 1003 | 1004 | 1005 | 1006 | public class ExplorerItem { 1007 | 1008 | public ExplorerItem(IStorageItem item) { 1009 | string label = (item is StorageFile) ? "file" : "folder"; 1010 | 1011 | if (label == "file" && ".pdf".Contains(((StorageFile)item).FileType.ToLower())) { 1012 | label = "pdf"; 1013 | } 1014 | SetExplorerListItem(item, item.Name, label); 1015 | } 1016 | public ExplorerItem(PdfPage item, String name) { 1017 | 1018 | SetExplorerListItem(item, name, "pdfPage"); 1019 | } 1020 | 1021 | public void SetExplorerListItem(object data, string name, string label) { 1022 | Data = data; 1023 | Name = name; 1024 | Label = label; 1025 | 1026 | 1027 | if (label == "file") { 1028 | ItemSymbol = "\uEB9F"; 1029 | } else if (label == "folder") { 1030 | ItemSymbol = "\uED43"; 1031 | } else if (label == "pdf") { 1032 | ItemSymbol = "\uEA90"; 1033 | } else if (label == "pdfPage") { 1034 | ItemSymbol = "\uE7C3"; 1035 | } 1036 | } 1037 | 1038 | public object Data { get; set; } 1039 | public string Name { get; set; } 1040 | public string Label { get; set; } 1041 | public string ItemSymbol { get; set; } 1042 | 1043 | public override string ToString() => Name; 1044 | 1045 | 1046 | 1047 | public async Task> GetChildItemList() { 1048 | if (Label == "folder") { 1049 | return await GetFolderChildItem((StorageFolder)Data); 1050 | } else if (Label == "pdf") { 1051 | return await GetPdfChildItem((StorageFile)Data); 1052 | } 1053 | return null; 1054 | } 1055 | 1056 | public async Task> GetPdfChildItem(StorageFile file) { 1057 | 1058 | //https://blog.pieeatingninjas.be/2016/02/06/displaying-pdf-files-in-a-uwp-app/ 1059 | //https://pspdfkit.com/blog/2019/open-pdf-in-uwp/ 1060 | 1061 | List childList = new List(); 1062 | PdfDocument doc = await PdfDocument.LoadFromFileAsync(file); 1063 | 1064 | for (uint i = 0; i < doc.PageCount; i++) { 1065 | PdfPage pdfPage = doc.GetPage(i); 1066 | childList.Add(new ExplorerItem(pdfPage, pdfPage.Index.ToString() + "_" + file.Name)); 1067 | } 1068 | return childList; 1069 | } 1070 | 1071 | public async Task> GetFolderChildItem(StorageFolder folder) { 1072 | List childList = new List(); 1073 | 1074 | try { 1075 | foreach (IStorageItem item in await folder.GetItemsAsync()) { 1076 | if (item is StorageFile) { 1077 | var fileItem = item as StorageFile; 1078 | //check isImage 1079 | if (new List() { ".jpeg", ".jpg", ".png", ".gif", ".tiff", ".bmp", ".pdf" }.Contains(fileItem.FileType.ToLower())) { 1080 | childList.Add(new ExplorerItem(item)); 1081 | } 1082 | } else if (item is StorageFolder) { 1083 | childList.Add(new ExplorerItem(item)); 1084 | } 1085 | } 1086 | } catch (Exception e) { 1087 | Debug.WriteLine(e.ToString()); 1088 | } 1089 | return childList; 1090 | 1091 | } 1092 | 1093 | 1094 | public async Task GetBitmapImage() { 1095 | 1096 | if (Label == "pdfPage") { 1097 | return await LoadPdfPageImage((PdfPage)Data); 1098 | } else if (Label == "file") { 1099 | return await ImageProcessor.LoadImage((StorageFile)Data); 1100 | } 1101 | return null; 1102 | } 1103 | 1104 | 1105 | private async Task LoadPdfPageImage(PdfPage page) { 1106 | 1107 | using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream()) { 1108 | await page.RenderToStreamAsync(stream); 1109 | var decoder = await BitmapDecoder.CreateAsync(stream); 1110 | SoftwareBitmap bitmapItem = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied); 1111 | return bitmapItem; 1112 | } 1113 | } 1114 | 1115 | public static implicit operator string(ExplorerItem v) { 1116 | throw new NotImplementedException(); 1117 | } 1118 | } 1119 | 1120 | /// 1121 | /// crop box coordinate 1122 | /// 1123 | class BoxCoordinates { 1124 | int _initialPointX, _initialPointY; 1125 | int _maxWidth, _maxHeight; 1126 | public int X, Y, W, H; 1127 | 1128 | public BoxCoordinates(int x, int y, int maxWidth, int maxHeight) { 1129 | _initialPointX = x; 1130 | _initialPointY = y; 1131 | _maxWidth = maxWidth; 1132 | _maxHeight = maxHeight; 1133 | UpdateCoordinates(x, y); 1134 | } 1135 | 1136 | public void UpdateCoordinates(int X, int Y) { 1137 | X = Math.Max(Math.Min(X, _maxWidth), 0); 1138 | Y = Math.Max(Math.Min(Y, _maxHeight), 0); 1139 | 1140 | this.X = Math.Min(_initialPointX, X); 1141 | this.Y = Math.Min(_initialPointY, Y); 1142 | 1143 | W = Math.Max(_initialPointX, X) - this.X; 1144 | H = Math.Max(_initialPointY, Y) - this.Y; 1145 | 1146 | W = Math.Min(W, _maxWidth - this.X); 1147 | H = Math.Min(H, _maxHeight - this.Y); 1148 | } 1149 | 1150 | public (uint, uint, uint, uint) GetRatioXYWH(double NewWidth, double NewHeight) { 1151 | double ratioWidth = NewWidth / _maxWidth; 1152 | double ratioHeight = NewHeight / _maxHeight; 1153 | uint x = (uint)(X * ratioWidth); 1154 | uint y = (uint)(Y * ratioHeight); 1155 | uint w = (uint)(W * ratioWidth); 1156 | uint h = (uint)(H * ratioHeight); 1157 | return (x, y, w, h); 1158 | } 1159 | 1160 | } 1161 | 1162 | } 1163 | -------------------------------------------------------------------------------- /ImageScanOCR/Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | Image Scan OCR 19 | ttop324 20 | Assets\StoreLogo.png 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /ImageScanOCR/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해 6 | // 제어됩니다. 어셈블리와 관련된 정보를 수정하려면 7 | // 이러한 특성 값을 변경하세요. 8 | [assembly: AssemblyTitle("ImageScanOCR")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ImageScanOCR")] 13 | [assembly: AssemblyCopyright("Copyright © 2021")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다. 18 | // 19 | // 주 버전 20 | // 부 버전 21 | // 빌드 번호 22 | // 수정 버전 23 | // 24 | // 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를 25 | // 기본값으로 할 수 있습니다. 26 | // [assembly: AssemblyVersion("1.0.*")] 27 | [assembly: AssemblyVersion("1.0.0.0")] 28 | [assembly: AssemblyFileVersion("1.0.0.0")] 29 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /ImageScanOCR/Properties/Default.rd.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 daniel k 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ImageScanOCR 2 | Image Scan OCR recognize text from image and PDF using Window OCR. 3 | This OCR app convert given text image to editable plain text. 4 | User can handle its plain text and can save OCR result text as plain text file. 5 | download from [microsoft store](https://www.microsoft.com/en-us/p/image-scan-ocr/9pjhnq2r5kg7?activetab=pivot:overviewtab) 6 | 7 | [microsoft store](https://www.microsoft.com/en-us/p/image-scan-ocr/9pjhnq2r5kg7?activetab=pivot:overviewtab) 8 | [softpedia](https://www.softpedia.com/get/Office-tools/Other-Office-Tools/Image-Scan-OCR.shtml) 9 | 10 | 11 | # Result 12 | ![result](doc/screenshot_1.png) 13 | ![result](doc/screenshot_2.png) 14 | ![result](doc/screenshot_3.png) 15 | 16 | 17 | # Features 18 | - Convert image to editable text 19 | - PDF file can be opened to process OCR 20 | - User can edit OCR result text and save text as file 21 | - OCR result text can be copied into user clipboard 22 | - Uses Window OCR API to support offline OCR process 23 | - Support multiple OCR language when Window language pack installed 24 | - User can select folder to search OCR required file 25 | - Process all image once using batch OCR processing 26 | - Rotate image to process OCR correctly 27 | - User can vary OCR text result display mode 28 | - Able to see sentence splitted OCR text result 29 | 30 | 31 | # Required environment to run 32 | - [winui2-getting-started](https://docs.microsoft.com/en-us/windows/apps/winui/winui2/getting-started) 33 | - https://www.nuget.org/packages/Microsoft.UI.Xaml 34 | - [communitytoolkit-getting-started](https://docs.microsoft.com/en-us/windows/communitytoolkit/getting-started) 35 | - https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.UI.Controls/ 36 | 37 | # Privacy policy 38 | - Image Scan OCR uses user data only for Window OCR process purpose. 39 | - It does not share any user data with any other third parties. 40 | - It does not store any personal data, images, or OCR result text 41 | 42 | # Change log 43 | - 1.0.12 44 | - fix folder open crash 45 | - 1.0.11 46 | - fix EXIF oritentation 47 | - fix keyboard file selection 48 | - fix textwrap 49 | - fix capture cancle button 50 | - 1.0.10 51 | - fix image resize crash 52 | - 1.0.9 53 | - support OCR on screen capture 54 | - 1.0.8 55 | - fix batch processing 56 | - add "add language" button 57 | - 1.0.7 58 | - make feature that refresh file explorer panel automatically 59 | - allow drag and drop image file into image panel 60 | - able to crop image file to process ocr 61 | - 1.0.6 - 1.0.3 62 | - Apply WinUI Mica 63 | - Add tooltip to alert OCR language pack install 64 | - Support batch OCR processing 65 | - Support OCR on pdf 66 | - Reopen previous opened folder 67 | - Support rotation on OCR image 68 | - Support text wrap on OCR result text 69 | - Support OCR result text to split by sentence 70 | - 1.0.2 71 | - First release 72 | 73 | # Acknowledgement and References 74 | - [winui2-getting-started](https://docs.microsoft.com/en-us/windows/apps/winui/winui2/getting-started) 75 | - [communitytoolkit-getting-started](https://docs.microsoft.com/en-us/windows/apps/winui/winui2/getting-started) 76 | - [window-ocr-kaki104](https://kaki104.tistory.com/491) 77 | - [window-ocr-rkttu](https://velog.io/@rkttu/csharp-win10-ocr-howto) 78 | - [Windows-universal-samples-ocr](https://github.com/microsoft/windows-universal-samples/tree/main/Samples/OCR) 79 | - [acrylic](https://docs.microsoft.com/ko-kr/windows/apps/design/style/acrylic) 80 | - [gridsplitter](https://docs.microsoft.com/en-us/windows/communitytoolkit/controls/gridsplitter) 81 | - [breadcrumbbar](https://docs.microsoft.com/ko-kr/windows/apps/design/controls/breadcrumbbar) 82 | - [file-access-permissions](https://docs.microsoft.com/en-us/windows/uwp/files/file-access-permissions) 83 | - [window-store-deploy](https://codedragon.tistory.com/3209) 84 | - [ocr_icon](https://www.flaticon.com/premium-icon/ocr_5558190) 85 | - [stop-task-when-task-run](https://stackoverflow.com/questions/36911609/stop-task-when-task-run) 86 | - [BarcodeScanner](https://github.com/kiwamu25/BarcodeScanner/blob/f5359693019ea957813b364b456bba571f881060/BarcodeScanner/BarcodeScanner/MainPage.xaml.cs) 87 | - [displaying-pdf-files-in-a-uwp-app](https://blog.pieeatingninjas.be/2016/02/06/displaying-pdf-files-in-a-uwp-app/) 88 | - [open-pdf-in-uwp](https://pspdfkit.com/blog/2019/open-pdf-in-uwp/) 89 | - [flyouts/teaching-tip](https://docs.microsoft.com/ko-kr/windows/apps/design/controls/dialogs-and-flyouts/teaching-tip) 90 | - [launch-settings-app](https://docs.microsoft.com/en-us/windows/uwp/launch-resume/launch-settings-app) 91 | - [how-to-access-files-or-folders](https://stackoverflow.com/questions/52227435/how-to-access-files-or-folders-the-user-picked-in-a-previous-session-of-my-uwp-a) 92 | - [segoe-ui-symbol-font](https://docs.microsoft.com/en-us/windows/apps/design/style/segoe-ui-symbol-font) 93 | - [mica](https://docs.microsoft.com/en-us/windows/apps/design/style/mica) 94 | - [Rise-Notes](https://github.com/Rise-Software/Rise-Notes) 95 | - [window store delploy](https://codedragon.tistory.com/3209) 96 | - [softpedia](https://www.softpedia.com/get/Office-tools/Other-Office-Tools/Image-Scan-OCR.shtml) 97 | - [review by gigafree](https://www.gigafree.net/tool/ocr/Image-Scan-OCR.html) 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /doc/dummy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/dummy.pdf -------------------------------------------------------------------------------- /doc/microsoft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/microsoft.png -------------------------------------------------------------------------------- /doc/ocr_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/ocr_128.png -------------------------------------------------------------------------------- /doc/ocr_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/ocr_16.png -------------------------------------------------------------------------------- /doc/ocr_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/ocr_24.png -------------------------------------------------------------------------------- /doc/ocr_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/ocr_256.png -------------------------------------------------------------------------------- /doc/ocr_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/ocr_32.png -------------------------------------------------------------------------------- /doc/ocr_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/ocr_512.png -------------------------------------------------------------------------------- /doc/ocr_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/ocr_64.png -------------------------------------------------------------------------------- /doc/privacy_policy.md: -------------------------------------------------------------------------------- 1 | # Privacy policy 2 | - Image Scan OCR uses user data only for Window OCR process purpose. 3 | - It does not share any user data with any other third parties. 4 | - It does not store any personal data, images, or OCR result text -------------------------------------------------------------------------------- /doc/screenshot_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/screenshot_1.png -------------------------------------------------------------------------------- /doc/screenshot_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/screenshot_2.png -------------------------------------------------------------------------------- /doc/screenshot_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/screenshot_3.png -------------------------------------------------------------------------------- /doc/screenshot_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/screenshot_4.png -------------------------------------------------------------------------------- /doc/softpedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/softpedia.png -------------------------------------------------------------------------------- /doc/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttop32/ImageScanOCR/8a96313c00957b912b3be55bc65d705a237a300f/doc/test.png --------------------------------------------------------------------------------