From bf8f2f89fcb0baaa645296efaff5b9042c0f784b Mon Sep 17 00:00:00 2001 From: Adit Date: Thu, 25 Sep 2025 17:58:19 +0530 Subject: [PATCH 1/4] Example of Aspose OCR --- aspose-ocr/.gitignore | 5 ++ aspose-ocr/Apps/ImageToTextApp.cs | 59 +++++++++++++++++++ .../OCR/Aspose/AsposeOCRService.cs | 29 +++++++++ aspose-ocr/Connections/OCR/IOCRService.cs | 6 ++ aspose-ocr/Connections/OCR/OCRConnection.cs | 31 ++++++++++ aspose-ocr/GlobalUsings.cs | 29 +++++++++ aspose-ocr/Ivy.Aspose.OCR.Examples.csproj | 28 +++++++++ aspose-ocr/Ivy.Aspose.OCR.Examples.sln | 25 ++++++++ aspose-ocr/Program.cs | 12 ++++ aspose-ocr/README.md | 17 ++++++ 10 files changed, 241 insertions(+) create mode 100644 aspose-ocr/.gitignore create mode 100644 aspose-ocr/Apps/ImageToTextApp.cs create mode 100644 aspose-ocr/Connections/OCR/Aspose/AsposeOCRService.cs create mode 100644 aspose-ocr/Connections/OCR/IOCRService.cs create mode 100644 aspose-ocr/Connections/OCR/OCRConnection.cs create mode 100644 aspose-ocr/GlobalUsings.cs create mode 100644 aspose-ocr/Ivy.Aspose.OCR.Examples.csproj create mode 100644 aspose-ocr/Ivy.Aspose.OCR.Examples.sln create mode 100644 aspose-ocr/Program.cs create mode 100644 aspose-ocr/README.md diff --git a/aspose-ocr/.gitignore b/aspose-ocr/.gitignore new file mode 100644 index 00000000..2cb90536 --- /dev/null +++ b/aspose-ocr/.gitignore @@ -0,0 +1,5 @@ +bin/ +obj/ +*.sln.iml +.idea/**/* +**/.idea/* \ No newline at end of file diff --git a/aspose-ocr/Apps/ImageToTextApp.cs b/aspose-ocr/Apps/ImageToTextApp.cs new file mode 100644 index 00000000..878b625f --- /dev/null +++ b/aspose-ocr/Apps/ImageToTextApp.cs @@ -0,0 +1,59 @@ +using Ivy.Aspose.OCR.Examples.Connections.OCR; + +namespace Ivy.Aspose.OCR.Examples.Apps; + +[App(icon: Icons.FileImage, path: ["Apps"])] +public class ImageToTextApp : ViewBase +{ + public override object? Build() + { + var outputText = this.UseState(""); + var client = UseService(); + + var error = UseState(() => null); + var ocrService = UseService(); + var files = UseState(() => null); + + var uploadUrl = this.UseUpload( + fileBytes => + { + if (fileBytes.Length > 1 * 1024 * 1024) // 1MB limit + { + client.Toast("File size must be less than 1MB", "Validation Error"); + error.Set("File size must be less than 1MB"); + return; + } + + error.Set((string?)null); + // Process uploaded file bytes + Console.WriteLine($"Received {fileBytes.Length} bytes"); + }, + "image/jpeg", + "uploaded-image" + ); + + return Layout.Vertical( + Text.H1("Convert Image to text online").Color(Colors.Green), + Text.Block("Free OCR software to convert images or screenshots to text online"), + error.Value != null + ? new Callout(error.Value, variant: CalloutVariant.Error) + : null, + files.ToFileInput(uploadUrl, "Upload Image").Accept(".jpg,.jpeg,.png"), + new Button("Recognize", _ => + { + if (error.Value == null && files.Value != null) + { + var file = files.Value; + + // TODO: file.Content is getting null or empty + using var ms = new MemoryStream(file.Content); + outputText.Value = ocrService.ExtractText(ms); + + Console.WriteLine($"extracted Text: {outputText.Value}"); + } + }), + Text.Block("Output Text:"), + new ObservableView(outputText) + ).Align(Align.Center); + } +} diff --git a/aspose-ocr/Connections/OCR/Aspose/AsposeOCRService.cs b/aspose-ocr/Connections/OCR/Aspose/AsposeOCRService.cs new file mode 100644 index 00000000..2b00f274 --- /dev/null +++ b/aspose-ocr/Connections/OCR/Aspose/AsposeOCRService.cs @@ -0,0 +1,29 @@ +using Aspose.OCR; + +namespace Ivy.Aspose.OCR.Examples.Connections.OCR.Aspose; + +public class AsposeOcrService: IOCRService +{ + private readonly AsposeOcr recognitionEngine; + + public AsposeOcrService() + { + recognitionEngine = new AsposeOcr(); + } + + public string ExtractText(MemoryStream imageStream) + { + // Add image to the recognition batch + var source = new OcrInput(InputType.SingleImage); + source.Add(imageStream); + + // Perform OCR + List results + = recognitionEngine.Recognize(source); + + // OCR processing + var result = results[0].RecognitionText; + + return result; + } +} diff --git a/aspose-ocr/Connections/OCR/IOCRService.cs b/aspose-ocr/Connections/OCR/IOCRService.cs new file mode 100644 index 00000000..0dc91164 --- /dev/null +++ b/aspose-ocr/Connections/OCR/IOCRService.cs @@ -0,0 +1,6 @@ +namespace Ivy.Aspose.OCR.Examples.Connections.OCR; + +public interface IOCRService +{ + string ExtractText(MemoryStream imageStream); +} diff --git a/aspose-ocr/Connections/OCR/OCRConnection.cs b/aspose-ocr/Connections/OCR/OCRConnection.cs new file mode 100644 index 00000000..b73224a6 --- /dev/null +++ b/aspose-ocr/Connections/OCR/OCRConnection.cs @@ -0,0 +1,31 @@ +using Ivy.Aspose.OCR.Examples.Connections.OCR.Aspose; +using Ivy.Connections; + +namespace Ivy.Aspose.OCR.Examples.Connections.OCR; + +public class OCRConnection : IConnection +{ + public string GetConnectionType() + { + return typeof(OCRConnection).ToString(); + } + + public string GetContext(string connectionPath) + { + throw new NotImplementedException(); + } + + public ConnectionEntity[] GetEntities() + { + throw new NotImplementedException(); + } + + public string GetName() => nameof(OCRConnection); + + public string GetNamespace() => typeof(OCRConnection).Namespace; + + public void RegisterServices(IServiceCollection services) + { + services.AddScoped(); + } +} diff --git a/aspose-ocr/GlobalUsings.cs b/aspose-ocr/GlobalUsings.cs new file mode 100644 index 00000000..1fecd23e --- /dev/null +++ b/aspose-ocr/GlobalUsings.cs @@ -0,0 +1,29 @@ +global using Ivy; +global using Ivy.Apps; +global using Ivy.Auth; +global using Ivy.Chrome; +global using Ivy.Client; +global using Ivy.Core; +global using Ivy.Core.Hooks; +global using Ivy.Helpers; +global using Ivy.Hooks; +global using Ivy.Shared; +global using Ivy.Services; +global using Ivy.Views; +global using Ivy.Views.Alerts; +global using Ivy.Views.Blades; +global using Ivy.Views.Builders; +global using Ivy.Views.Charts; +global using Ivy.Views.Dashboards; +global using Ivy.Views.Forms; +global using Ivy.Views.Tables; +global using Ivy.Widgets.Inputs; +global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Logging; +global using System.Collections.Immutable; +global using System.ComponentModel.DataAnnotations; +global using System.Globalization; +global using System.Reactive.Linq; + +namespace Ivy.Aspose.OCR.Examples; diff --git a/aspose-ocr/Ivy.Aspose.OCR.Examples.csproj b/aspose-ocr/Ivy.Aspose.OCR.Examples.csproj new file mode 100644 index 00000000..daa0fe42 --- /dev/null +++ b/aspose-ocr/Ivy.Aspose.OCR.Examples.csproj @@ -0,0 +1,28 @@ + + + + Exe + net9.0 + enable + enable + CS8618;CS8603;CS8602;CS8604;CS9113 + Ivy.Aspose.OCR.Examples + + + + + + + + + + + + + + + + + + + diff --git a/aspose-ocr/Ivy.Aspose.OCR.Examples.sln b/aspose-ocr/Ivy.Aspose.OCR.Examples.sln new file mode 100644 index 00000000..5963229b --- /dev/null +++ b/aspose-ocr/Ivy.Aspose.OCR.Examples.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36429.23 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ivy.Aspose.OCR.Examples", "Ivy.Aspose.OCR.Examples.csproj", "{BA2A13B0-78C9-203B-1462-034AD42E4D37}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BA2A13B0-78C9-203B-1462-034AD42E4D37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA2A13B0-78C9-203B-1462-034AD42E4D37}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA2A13B0-78C9-203B-1462-034AD42E4D37}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA2A13B0-78C9-203B-1462-034AD42E4D37}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {24B5F0F2-14B2-4944-9817-4606E84F19E2} + EndGlobalSection +EndGlobal diff --git a/aspose-ocr/Program.cs b/aspose-ocr/Program.cs new file mode 100644 index 00000000..ec65983e --- /dev/null +++ b/aspose-ocr/Program.cs @@ -0,0 +1,12 @@ + +CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US"); +var server = new Server(); +#if DEBUG +server.UseHotReload(); +#endif +server.AddAppsFromAssembly(); +server.AddConnectionsFromAssembly(); +var chromeSettings = new ChromeSettings() + .UseTabs(preventDuplicates: true); +server.UseChrome(chromeSettings); +await server.RunAsync(); diff --git a/aspose-ocr/README.md b/aspose-ocr/README.md new file mode 100644 index 00000000..263e0653 --- /dev/null +++ b/aspose-ocr/README.md @@ -0,0 +1,17 @@ +# Ivy.Aspose.OCR.Examples + +Web application created using [Ivy](https://github.com/Ivy-Interactive/Ivy). + +Ivy is a web framework for building interactive web applications using C# and .NET. + +## Run + +``` +dotnet watch +``` + +## Deploy + +``` +ivy deploy +``` \ No newline at end of file From a567ada6d282b04947a3896cd017a4634dd42478 Mon Sep 17 00:00:00 2001 From: Adit Date: Fri, 26 Sep 2025 12:49:20 +0530 Subject: [PATCH 2/4] Update the PR fixes and modify readme --- aspose-ocr/Apps/ImageToTextApp.cs | 29 ++++++++---------- aspose-ocr/Apps/aspose-OCR-image-to-text.png | Bin 0 -> 41492 bytes .../OCR/Aspose/AsposeOCRService.cs | 8 +++-- aspose-ocr/Ivy.Aspose.OCR.Examples.csproj | 5 --- aspose-ocr/README.md | 15 ++++++--- 5 files changed, 30 insertions(+), 27 deletions(-) create mode 100644 aspose-ocr/Apps/aspose-OCR-image-to-text.png diff --git a/aspose-ocr/Apps/ImageToTextApp.cs b/aspose-ocr/Apps/ImageToTextApp.cs index 878b625f..ec7c6255 100644 --- a/aspose-ocr/Apps/ImageToTextApp.cs +++ b/aspose-ocr/Apps/ImageToTextApp.cs @@ -1,4 +1,5 @@ using Ivy.Aspose.OCR.Examples.Connections.OCR; +using System.IO; namespace Ivy.Aspose.OCR.Examples.Apps; @@ -8,25 +9,24 @@ public class ImageToTextApp : ViewBase public override object? Build() { var outputText = this.UseState(""); - var client = UseService(); + var ocrService = UseService(); var error = UseState(() => null); - var ocrService = UseService(); var files = UseState(() => null); + var fileBytes = UseState(() => null); // Store the actual file bytes var uploadUrl = this.UseUpload( - fileBytes => + uploadedBytes => { - if (fileBytes.Length > 1 * 1024 * 1024) // 1MB limit + if (uploadedBytes.Length > 1 * 1024 * 1024) // 1MB limit { - client.Toast("File size must be less than 1MB", "Validation Error"); error.Set("File size must be less than 1MB"); + fileBytes.Set((byte[]?)null); // Clear stored bytes on error return; } error.Set((string?)null); - // Process uploaded file bytes - Console.WriteLine($"Received {fileBytes.Length} bytes"); + fileBytes.Set(uploadedBytes); // Store the file bytes for later use }, "image/jpeg", "uploaded-image" @@ -38,22 +38,19 @@ public class ImageToTextApp : ViewBase error.Value != null ? new Callout(error.Value, variant: CalloutVariant.Error) : null, - files.ToFileInput(uploadUrl, "Upload Image").Accept(".jpg,.jpeg,.png"), + files.ToFileInput(uploadUrl, "Upload Image").Accept("image/*"), new Button("Recognize", _ => { - if (error.Value == null && files.Value != null) + if (error.Value == null && fileBytes.Value != null) { - var file = files.Value; - - // TODO: file.Content is getting null or empty - using var ms = new MemoryStream(file.Content); + // Use the stored file bytes instead of file.Content + using var ms = new MemoryStream(fileBytes.Value); outputText.Value = ocrService.ExtractText(ms); - - Console.WriteLine($"extracted Text: {outputText.Value}"); + fileBytes.Set((byte[]?)null); // Clear stored bytes once completed } }), Text.Block("Output Text:"), new ObservableView(outputText) ).Align(Align.Center); } -} +} \ No newline at end of file diff --git a/aspose-ocr/Apps/aspose-OCR-image-to-text.png b/aspose-ocr/Apps/aspose-OCR-image-to-text.png new file mode 100644 index 0000000000000000000000000000000000000000..858fc17259180dabd153949004ef7b8db99d171b GIT binary patch literal 41492 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 literal 0 HcmV?d00001 diff --git a/aspose-ocr/Connections/OCR/Aspose/AsposeOCRService.cs b/aspose-ocr/Connections/OCR/Aspose/AsposeOCRService.cs index 2b00f274..1e4a220f 100644 --- a/aspose-ocr/Connections/OCR/Aspose/AsposeOCRService.cs +++ b/aspose-ocr/Connections/OCR/Aspose/AsposeOCRService.cs @@ -20,9 +20,13 @@ public string ExtractText(MemoryStream imageStream) // Perform OCR List results = recognitionEngine.Recognize(source); - + // OCR processing - var result = results[0].RecognitionText; + string result = string.Empty; + if (results.Count > 0) + { + result = results[0].RecognitionText; + } return result; } diff --git a/aspose-ocr/Ivy.Aspose.OCR.Examples.csproj b/aspose-ocr/Ivy.Aspose.OCR.Examples.csproj index daa0fe42..fa5d1867 100644 --- a/aspose-ocr/Ivy.Aspose.OCR.Examples.csproj +++ b/aspose-ocr/Ivy.Aspose.OCR.Examples.csproj @@ -19,10 +19,5 @@ - - - - - diff --git a/aspose-ocr/README.md b/aspose-ocr/README.md index 263e0653..7e83f253 100644 --- a/aspose-ocr/README.md +++ b/aspose-ocr/README.md @@ -4,14 +4,21 @@ Web application created using [Ivy](https://github.com/Ivy-Interactive/Ivy). Ivy is a web framework for building interactive web applications using C# and .NET. +## How it works + +This web application demonstrates OCR (Optical Character Recognition) using Ivy and Aspose.OCR. Users can upload an image (JPEG, up to 1MB), and the app extracts text from the image using an OCR service. The workflow is: + +1. Upload an image using the provided form. +2. The app validates the file size and type. +3. On clicking "Recognize", the image is processed and text is extracted. +4. The recognized text is displayed on the page. + ## Run ``` dotnet watch ``` -## Deploy +## Output Screenshot -``` -ivy deploy -``` \ No newline at end of file +![OCR Output](aspose-OCR-image-to-text.png) \ No newline at end of file From 8bb087a5f0882c47840a575ca82dae9524d730ae Mon Sep 17 00:00:00 2001 From: Adit Date: Fri, 26 Sep 2025 12:56:03 +0530 Subject: [PATCH 3/4] Updated the readme file --- aspose-ocr/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aspose-ocr/README.md b/aspose-ocr/README.md index 7e83f253..bdc9f646 100644 --- a/aspose-ocr/README.md +++ b/aspose-ocr/README.md @@ -1,6 +1,6 @@ # Ivy.Aspose.OCR.Examples -Web application created using [Ivy](https://github.com/Ivy-Interactive/Ivy). +Web application created using [Ivy](https://github.com/Ivy-Interactive/Ivy-Framework). Ivy is a web framework for building interactive web applications using C# and .NET. @@ -21,4 +21,4 @@ dotnet watch ## Output Screenshot -![OCR Output](aspose-OCR-image-to-text.png) \ No newline at end of file +![OCR Example](Apps/aspose-OCR-image-to-text.png) From b36db5f0a52386fd8a9728482ad689aa247edaf5 Mon Sep 17 00:00:00 2001 From: Adit Date: Sun, 28 Sep 2025 11:25:54 +0530 Subject: [PATCH 4/4] Set the APP default opens --- aspose-ocr/Program.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aspose-ocr/Program.cs b/aspose-ocr/Program.cs index ec65983e..a2ad299e 100644 --- a/aspose-ocr/Program.cs +++ b/aspose-ocr/Program.cs @@ -1,4 +1,6 @@ +using Ivy.Aspose.OCR.Examples.Apps; + CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US"); var server = new Server(); #if DEBUG @@ -7,6 +9,7 @@ server.AddAppsFromAssembly(); server.AddConnectionsFromAssembly(); var chromeSettings = new ChromeSettings() + .DefaultApp() .UseTabs(preventDuplicates: true); server.UseChrome(chromeSettings); await server.RunAsync();