diff --git a/.devcontainer/aspose-ocr/devcontainer.json b/.devcontainer/aspose-ocr/devcontainer.json new file mode 100644 index 00000000..b75978d9 --- /dev/null +++ b/.devcontainer/aspose-ocr/devcontainer.json @@ -0,0 +1,27 @@ +{ + "name": "Aspose OCR", + "image": "mcr.microsoft.com/dotnet/sdk:9.0", + "features": {}, + "workspaceFolder": "/workspaces/Ivy-Examples/aspose-ocr", + "postCreateCommand": "dotnet tool install -g Ivy.Console", + "postStartCommand": "dotnet watch", + "forwardPorts": [5010], + "portsAttributes": { + "5010": { + "label": "Aspose OCR", + "onAutoForward": "openPreview" + } + }, + "customizations": { + "vscode": { + "extensions": [ + "ms-dotnettools.csharp", + "ms-vscode.powershell", + "ms-dotnettools.csdevkit" + ] + }, + "codespaces": { + "openFiles": ["Apps/ImageToTextApp.cs"] + } + } + } \ No newline at end of file diff --git a/aspose-ocr/Apps/ImageToTextApp.cs b/aspose-ocr/Apps/ImageToTextApp.cs index ec7c6255..754788ec 100644 --- a/aspose-ocr/Apps/ImageToTextApp.cs +++ b/aspose-ocr/Apps/ImageToTextApp.cs @@ -1,7 +1,7 @@ -using Ivy.Aspose.OCR.Examples.Connections.OCR; +using Aspose.OCR; using System.IO; -namespace Ivy.Aspose.OCR.Examples.Apps; +namespace AsposeOcrExample.Apps; [App(icon: Icons.FileImage, path: ["Apps"])] public class ImageToTextApp : ViewBase @@ -9,7 +9,6 @@ public class ImageToTextApp : ViewBase public override object? Build() { var outputText = this.UseState(""); - var ocrService = UseService(); var error = UseState(() => null); var files = UseState(() => null); @@ -32,25 +31,44 @@ public class ImageToTextApp : ViewBase "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("image/*"), - new Button("Recognize", _ => - { - if (error.Value == null && fileBytes.Value != null) + var leftCard = new Card( + Layout.Vertical().Gap(6).Padding(3) + | Text.H2("Input") + | Text.Muted("Upload an image and run OCR") + | (error.Value != null ? new Callout(error.Value, variant: CalloutVariant.Error) : null) + | files.ToFileInput(uploadUrl, "Upload Image").Accept("image/*") + | new Button("Recognize").Primary().Icon(Icons.Eye) + .HandleClick(() => { - // Use the stored file bytes instead of file.Content - using var ms = new MemoryStream(fileBytes.Value); - outputText.Value = ocrService.ExtractText(ms); - fileBytes.Set((byte[]?)null); // Clear stored bytes once completed - } - }), - Text.Block("Output Text:"), - new ObservableView(outputText) - ).Align(Align.Center); + if (error.Value == null && fileBytes.Value != null) + { + using var ms = new MemoryStream(fileBytes.Value); + + var recognitionEngine = new AsposeOcr(); + using var source = new OcrInput(InputType.SingleImage); + source.Add(ms); + + var results = recognitionEngine.Recognize(source); + outputText.Value = results.Count > 0 ? results[0].RecognitionText : string.Empty; + fileBytes.Set((byte[]?)null); + } + }) + | Text.Small("This demo uses Aspose.OCR for .NET to recognize text.") + | Text.Markdown("Built with [Ivy Framework](https://github.com/Ivy-Interactive/Ivy-Framework) and [Aspose.OCR for .NET](https://products.aspose.com/ocr/net/)") + ).Width(Size.Fraction(0.45f)).Height(130); + + var rightCardBody = Layout.Vertical().Gap(4) + | Text.H2("Recognized Text") + | Text.Muted("Output") + | outputText.ToCodeInput() + .Width(Size.Full()) + .Height(Size.Units(70)) + .Language(Languages.Text); + + var rightCard = new Card(rightCardBody).Width(Size.Fraction(0.45f)).Height(130); + + return Layout.Horizontal().Gap(6).Align(Align.Center) + | leftCard + | rightCard; } } \ 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 deleted file mode 100644 index 858fc172..00000000 Binary files a/aspose-ocr/Apps/aspose-OCR-image-to-text.png and /dev/null differ diff --git a/aspose-ocr/Ivy.Aspose.OCR.Examples.csproj b/aspose-ocr/AsposeOcrExample.csproj similarity index 80% rename from aspose-ocr/Ivy.Aspose.OCR.Examples.csproj rename to aspose-ocr/AsposeOcrExample.csproj index fa5d1867..b7b39111 100644 --- a/aspose-ocr/Ivy.Aspose.OCR.Examples.csproj +++ b/aspose-ocr/AsposeOcrExample.csproj @@ -6,7 +6,7 @@ enable enable CS8618;CS8603;CS8602;CS8604;CS9113 - Ivy.Aspose.OCR.Examples + AsposeOcrExample @@ -17,7 +17,7 @@ - + diff --git a/aspose-ocr/Ivy.Aspose.OCR.Examples.sln b/aspose-ocr/AsposeOcrExample.sln similarity index 86% rename from aspose-ocr/Ivy.Aspose.OCR.Examples.sln rename to aspose-ocr/AsposeOcrExample.sln index 5963229b..9d0cabfc 100644 --- a/aspose-ocr/Ivy.Aspose.OCR.Examples.sln +++ b/aspose-ocr/AsposeOcrExample.sln @@ -3,7 +3,7 @@ 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}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsposeOcrExample", "AsposeOcrExample.csproj", "{BA2A13B0-78C9-203B-1462-034AD42E4D37}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/aspose-ocr/Connections/OCR/Aspose/AsposeOCRService.cs b/aspose-ocr/Connections/OCR/Aspose/AsposeOCRService.cs deleted file mode 100644 index 1e4a220f..00000000 --- a/aspose-ocr/Connections/OCR/Aspose/AsposeOCRService.cs +++ /dev/null @@ -1,33 +0,0 @@ -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 - string result = string.Empty; - if (results.Count > 0) - { - result = results[0].RecognitionText; - } - - return result; - } -} diff --git a/aspose-ocr/Connections/OCR/IOCRService.cs b/aspose-ocr/Connections/OCR/IOCRService.cs deleted file mode 100644 index 0dc91164..00000000 --- a/aspose-ocr/Connections/OCR/IOCRService.cs +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100644 index b73224a6..00000000 --- a/aspose-ocr/Connections/OCR/OCRConnection.cs +++ /dev/null @@ -1,31 +0,0 @@ -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 index 1fecd23e..9a0a102d 100644 --- a/aspose-ocr/GlobalUsings.cs +++ b/aspose-ocr/GlobalUsings.cs @@ -26,4 +26,4 @@ global using System.Globalization; global using System.Reactive.Linq; -namespace Ivy.Aspose.OCR.Examples; +namespace AsposeOcrExample; diff --git a/aspose-ocr/Program.cs b/aspose-ocr/Program.cs index a2ad299e..eb3dd26f 100644 --- a/aspose-ocr/Program.cs +++ b/aspose-ocr/Program.cs @@ -1,6 +1,4 @@ - -using Ivy.Aspose.OCR.Examples.Apps; - +using AsposeOcrExample.Apps; CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US"); var server = new Server(); #if DEBUG @@ -8,8 +6,17 @@ #endif server.AddAppsFromAssembly(); server.AddConnectionsFromAssembly(); +var customHeader = Layout.Vertical().Gap(2) + | new Html(@" +
+ + + +
+ "); var chromeSettings = new ChromeSettings() .DefaultApp() - .UseTabs(preventDuplicates: true); + .UseTabs(preventDuplicates: true) + .Header(customHeader); server.UseChrome(chromeSettings); await server.RunAsync(); diff --git a/aspose-ocr/README.md b/aspose-ocr/README.md index bdc9f646..7539277d 100644 --- a/aspose-ocr/README.md +++ b/aspose-ocr/README.md @@ -1,24 +1,88 @@ -# Ivy.Aspose.OCR.Examples +# Aspose.OCR Image-to-Text -Web application created using [Ivy](https://github.com/Ivy-Interactive/Ivy-Framework). +Image + +## Created Using Ivy + +Web application created using [Ivy-Framework](https://github.com/Ivy-Interactive/Ivy-Framework). + +**Ivy** - The ultimate framework for building internal tools with LLM code generation by unifying front-end and back-end into a single C# codebase. With Ivy, you can build robust internal tools and dashboards using C# and AI assistance based on your existing database. Ivy is a web framework for building interactive web applications using C# and .NET. -## How it works +## Interactive Example For OCR (Image To Text) + +This example showcases extracting text from images using Aspose.OCR with a simple two-panel UI: upload on the left, recognized text on the right. + +**What This Application Does:** + +- **Upload Image**: Select an image file and run OCR +- **Text Extraction**: Recognize text from the uploaded image +- **Monospaced Viewer**: See output in a clean, plain-text viewer +- **Validation**: Basic size check with friendly error messages + +**Technical Implementation:** + +- Uses Aspose.OCR `AsposeOcr` with `OcrInput(InputType.SingleImage)` +- Adds uploaded image stream via `source.Add(stream)` and calls `Recognize` +- Shows the first `RecognitionResult.RecognitionText` in a `CodeInput` +- Single C# view (`Apps/ImageToTextApp.cs`) built with Ivy UI primitives + +## One-Click Development Environment + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=Ivy-Interactive%2FIvy-Examples&machine=standardLinux32gb&devcontainer_path=.devcontainer%2Faspose-ocr%2Fdevcontainer.json&location=EuropeWest) + +Click the badge above to open Ivy Examples repository in GitHub Codespaces with: +- **.NET 9.0** SDK pre-installed +- **Ready-to-run** development environment +- **No local setup** required + +## How to Run + +1. **Prerequisites**: .NET 9+ SDK +2. **Navigate to the example**: + ```bash + cd aspose-ocr + ``` +3. **Restore dependencies**: + ```bash + dotnet restore + ``` +4. **Run the application**: + ```bash + dotnet watch + ``` +5. **Open your browser** to the URL shown in the terminal (typically `http://localhost:5010`) + +## How to Deploy + +Deploy this example to Ivy's hosting platform: + +1. **Navigate to the example**: + ```bash + cd aspose-ocr + ``` +2. **Deploy to Ivy hosting**: + ```bash + ivy deploy + ``` +This will deploy your OCR application with a single command. + +## Licensing & Trial Limitations + +**Aspose.OCR for .NET** is a commercial library that can be used in trial (evaluation) mode without a license. -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: +### Trial Mode Restrictions -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. +When running without a license, the following limitations apply: -## Run +- If the recognized image contains **more than 300 characters**, only the **first 300 characters** are recognized. +- If the recognized image contains **less than 300 characters**, only the **first 60%** are recognized. -``` -dotnet watch -``` +For more licensing options (metered, embedded resources, stream), see the [official licensing documentation](https://docs.aspose.com/ocr/net/licensing/). -## Output Screenshot +## Learn More -![OCR Example](Apps/aspose-OCR-image-to-text.png) +- Aspose.OCR for .NET overview: [products.aspose.com/ocr/net](https://products.aspose.com/ocr/net/) +- Aspose.OCR Licensing: [docs.aspose.com/ocr/net/licensing](https://docs.aspose.com/ocr/net/licensing/) +- Ivy Documentation: [docs.ivy.app](https://docs.ivy.app) diff --git a/crm-vc/Vc.csproj b/crm-vc/Vc.csproj index 008d7b0f..743463d9 100644 --- a/crm-vc/Vc.csproj +++ b/crm-vc/Vc.csproj @@ -11,9 +11,9 @@ - +