بناء قارئ أحرف ضوئية (OCR) متقدم باستخدام Angular وخدمة Azure Computer Vision
مقدمة إلى قارئ الأحرف الضوئية (OCR) وخدمة Azure Computer Vision
في هذا المقال التقني، سنخوض رحلة شيقة لإنشاء تطبيق متكامل للتعرف البصري على الأحرف (OCR) باستخدام إطار عمل Angular الشهير لتطوير واجهة المستخدم الأمامية، وبالاستفادة من خدمة Azure Computer Vision Cognitive Service من مايكروسوفت أزور. تُعد Computer Vision إحدى خدمات الذكاء الاصطناعي القوية التي تمكن التطبيقات من تحليل المحتوى داخل الصور وفهمها.
سنركز بشكل خاص على ميزة OCR ضمن Computer Vision لاكتشاف واستخراج النصوص المطبوعة من الصور. لن يقتصر التطبيق على استخراج النص فحسب، بل سيتجاوز ذلك لتحديد اللغة التي كُتب بها النص. تدعم واجهة برمجة تطبيقات OCR حاليًا 25 لغة مختلفة، مما يجعلها أداة مرنة للتعامل مع محتوى متعدد اللغات.
المتطلبات الأساسية لبدء المشروع
لضمان سير عملية التطوير بسلاسة، تأكد من تثبيت المتطلبات التالية على جهازك:
- تثبيت أحدث إصدار
LTSمنNode.JS. يمكنك تنزيله من: https://nodejs.org/en/download/ - تثبيت واجهة سطر الأوامر لـ
Angular CLI. يمكنك تثبيتها من: https://cli.angular.io/ - تثبيت حزمة تطوير البرامج
.NET Core 3.1 SDK. متوفرة على: https://dotnet.microsoft.com/download/dotnet-core/3.1 - تثبيت أحدث إصدار من بيئة التطوير المتكاملة
Visual Studio 2019. يمكن الحصول عليها من: https://visualstudio.microsoft.com/downloads/ - حساب اشتراك في
Azure. يمكنك إنشاء حسابAzureمجاني من خلال: https://azure.microsoft.com/en-in/free/
الحصول على الكود المصدري وهيكلة المشروع
يمكنك الحصول على الكود المصدري الكامل للمشروع من مستودع GitHub. في هذا التطبيق، سنعتمد على واجهة خلفية مبنية باستخدام ASP.NET Core. يوفر استخدام ASP.NET Core عملية مصادقة مباشرة وآمنة للوصول إلى خدمات Azure Cognitive Services. وهذا يضمن أيضًا أن المستخدم النهائي لن يتمكن من الوصول المباشر إلى مفاتيح أو تفاصيل خدمات Cognitive Services، مما يعزز أمان التطبيق.
إنشاء مورد خدمة Azure Computer Vision Cognitive Service
للبدء في استخدام خدمة Computer Vision، يجب أولاً إنشاء مورد لها في بوابة Azure:
الخطوة 1: تسجيل الدخول والبحث عن الخدمات المعرفية
سجل الدخول إلى بوابة Azure. في شريط البحث العلوي، ابحث عن cognitive services (الخدمات المعرفية) ثم انقر على النتيجة المطابقة.

الخطوة 2: إضافة مورد جديد
في الشاشة التالية، انقر على زر Add (إضافة). سيؤدي ذلك إلى فتح صفحة سوق الخدمات المعرفية. ابحث عن Computer Vision في شريط البحث ثم انقر على نتيجة البحث. ستفتح صفحة واجهة برمجة تطبيقات Computer Vision API.

الخطوة 3: إنشاء مورد Computer Vision
انقر على زر Create (إنشاء) لإنشاء مورد Computer Vision جديد. في صفحة الإنشاء، املأ التفاصيل المطلوبة كما هو موضح أدناه:
- الاسم (
Name): امنح موردك اسمًا فريدًا. - الاشتراك (
Subscription): حدد نوع الاشتراك الخاص بك من القائمة المنسدلة. - طبقة التسعير (
Pricing tier): اختر طبقة التسعير المناسبة لاحتياجاتك وميزانيتك. - مجموعة الموارد (
Resource group): اختر مجموعة موارد موجودة أو أنشئ مجموعة جديدة.
بعد إدخال التفاصيل، انقر على زر Create (إنشاء).

الخطوة 4: استعراض المفتاح ونقطة النهاية
بعد نشر المورد بنجاح، انقر على زر “Go to resource” (الانتقال إلى المورد). ستتمكن من رؤية المفتاح (Key) ونقطة النهاية (endpoint) لمورد Computer Vision الذي تم إنشاؤه حديثًا.

احرص على تدوين المفتاح ونقطة النهاية، حيث سنستخدمهما لاحقًا في هذا المقال لاستدعاء واجهة برمجة تطبيقات Computer Vision OCR API من كود .NET الخاص بنا. القيم في الصورة أعلاه مخفية لأسباب تتعلق بالخصوصية.
إنشاء تطبيق ASP.NET Core
سنقوم الآن بإنشاء مشروع الواجهة الخلفية باستخدام ASP.NET Core:
الخطوة 1: إنشاء مشروع جديد في Visual Studio
افتح Visual Studio 2019 وانقر على “Create a new Project” (إنشاء مشروع جديد). سيتم فتح مربع حوار “Create a new Project”. حدد “ASP.NET Core Web Application” ثم انقر على Next (التالي).

الخطوة 2: تكوين المشروع
ستنتقل الآن إلى شاشة “Configure your new project” (تكوين مشروعك الجديد). قم بتوفير اسم لتطبيقك مثل ngComputerVision ثم انقر على Create (إنشاء).

سيتم توجيهك إلى شاشة “Create a new ASP.NET Core web application” (إنشاء تطبيق ويب جديد لـ ASP.NET Core). حدد “.NET Core” و “ASP.NET Core 3.1” من القوائم المنسدلة في الأعلى. بعد ذلك، حدد قالب مشروع “Angular” وانقر على Create (إنشاء).
الخطوة 3: هيكل مجلدات المشروع
سيؤدي هذا إلى إنشاء مشروعنا. يوضح هيكل المجلدات الخاص بالتطبيق أدناه:

يحتوي مجلد ClientApp على كود Angular لتطبيقنا. بينما تحتوي مجلدات Controllers على وحدات التحكم الخاصة بواجهات برمجة التطبيقات (API controllers). توجد مكونات Angular داخل مجلد ClientApp\src\app.
يحتوي القالب الافتراضي على عدد قليل من مكونات Angular. لن تؤثر هذه المكونات على تطبيقنا، ولكن لتبسيط الأمور، سنقوم بحذف مجلدات fetchdata و counter من مجلد ClientApp/app/components. بالإضافة إلى ذلك، يجب إزالة الإشارة إلى هذين المكونين من ملف app.module.ts لضمان عدم وجود أخطاء.
تثبيت مكتبة Computer Vision API
سنقوم بتثبيت مكتبة Azure Computer Vision API التي ستوفر لنا النماذج الجاهزة للتعامل مع استجابات Computer Vision REST API. لتثبيت الحزمة، انتقل إلى Tools >> NuGet Package Manager >> Package Manager Console (الأدوات >> مدير حزم NuGet >> وحدة تحكم مدير الحزم). ستفتح وحدة تحكم مدير الحزم. قم بتشغيل الأمر كما هو موضح أدناه:
Install-Package Microsoft.Azure.CognitiveServices.Vision.ComputerVision -Version 5.0 .0
يمكنك معرفة المزيد عن هذه الحزمة في معرض NuGet.
إنشاء النماذج (Models)
سنقوم بإنشاء بعض النماذج التي ستساعدنا في تنظيم البيانات داخل التطبيق:
الخطوة 1: إنشاء مجلد النماذج
انقر بزر الماوس الأيمن على مشروع ngComputerVision واختر Add >> New Folder (إضافة >> مجلد جديد). اسم المجلد Models.
الخطوة 2: إضافة فئة LanguageDetails.cs
مرة أخرى، انقر بزر الماوس الأيمن على مجلد Models واختر Add >> Class (إضافة >> فئة) لإضافة ملف فئة جديد. ضع اسم الفئة LanguageDetails.cs وانقر على Add (إضافة). افتح ملف LanguageDetails.cs وضع الكود التالي بداخله:
namespace ngComputerVision.Models
{
public class LanguageDetails
{
public string Name { get; set; }
public string NativeName { get; set; }
public string Dir { get; set; }
}
}
الخطوة 3: إضافة فئة AvailableLanguage.cs
وبالمثل، أضف ملف فئة جديد باسم AvailableLanguage.cs وضع الكود التالي بداخله:
using System.Collections.Generic;
namespace ngComputerVision.Models
{
public class AvailableLanguage
{
public Dictionary<string, LanguageDetails> Translation { get; set; }
}
}
الخطوة 4: إنشاء نماذج DTO (كائنات نقل البيانات)
سنضيف أيضًا فئتين ككائنات نقل البيانات (DTO - Data Transfer Object) لإرسال البيانات مرة أخرى إلى العميل. أنشئ مجلدًا جديدًا وسمه DTOModels.
إضافة فئة AvailableLanguageDTO.cs
أضف ملف فئة جديد AvailableLanguageDTO.cs في مجلد DTOModels وضع الكود التالي بداخله:
namespace ngComputerVision.DTOModels
{
public class AvailableLanguageDTO
{
public string LanguageID { get; set; }
public string LanguageName { get; set; }
}
}
إضافة فئة OcrResultDTO.cs
أضف ملف OcrResultDTO.cs وضع الكود التالي بداخله:
namespace ngComputerVision.DTOModels
{
public class OcrResultDTO
{
public string Language { get; set; }
public string DetectedText { get; set; }
}
}
إضافة وحدة التحكم OCR (OCR Controller)
سنضيف وحدة تحكم جديدة لتطبيقنا للتعامل مع طلبات التعرف على الصور:
الخطوة 1: إنشاء وحدة التحكم
انقر بزر الماوس الأيمن على مجلد Controllers واختر Add >> New Item (إضافة >> عنصر جديد). سيتم فتح مربع حوار “Add New Item” (إضافة عنصر جديد). حدد “Visual C#” من اللوحة اليسرى، ثم حدد “API Controller Class” من لوحة القوالب وضع الاسم OCRController.cs. انقر على Add (إضافة).

ستتولى وحدة التحكم OCRController معالجة طلبات التعرف على الصور الواردة من تطبيق العميل. وستقوم وحدة التحكم هذه أيضًا بإرجاع قائمة بجميع اللغات المدعومة بواسطة واجهة برمجة تطبيقات OCR.
الخطوة 2: كود OCRController.cs
افتح ملف OCRController.cs وضع الكود التالي بداخله:
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json.Linq;
using System.IO;
using Newtonsoft.Json;
using System.Text;
using ngComputerVision.Models;
using System.Collections.Generic;
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models;
using ngComputerVision.DTOModels;
namespace ngComputerVision.Controllers
{
[Produces("application/json")]
[Route("api/[controller]")]
public class OCRController : Controller
{
static string subscriptionKey;
static string endpoint;
static string uriBase;
public OCRController()
{
subscriptionKey = "b993f3afb4e04119bd8ed37171d4ec71";
endpoint = "https://ankitocrdemo.cognitiveservices.azure.com/";
uriBase = endpoint + "vision/v2.1/ocr";
}
[HttpPost, DisableRequestSizeLimit]
public async Task<OcrResultDTO> Post()
{
StringBuilder sb = new StringBuilder();
OcrResultDTO ocrResultDTO = new OcrResultDTO();
try
{
if (Request.Form.Files.Count > 0)
{
var file = Request.Form.Files[Request.Form.Files.Count - 1];
if (file.Length > 0)
{
var memoryStream = new MemoryStream();
file.CopyTo(memoryStream);
byte[] imageFileBytes = memoryStream.ToArray();
memoryStream.Flush();
string JSONResult = await ReadTextFromStream(imageFileBytes);
OcrResult ocrResult = JsonConvert.DeserializeObject<OcrResult>(JSONResult);
if (!ocrResult.Language.Equals("unk"))
{
foreach (OcrLine ocrLine in ocrResult.Regions[0].Lines)
{
foreach (OcrWord ocrWord in ocrLine.Words)
{
sb.Append(ocrWord.Text);
sb.Append(' ');
}
sb.AppendLine();
}
}
else
{
sb.Append("This language is not supported.");
}
ocrResultDTO.DetectedText = sb.ToString();
ocrResultDTO.Language = ocrResult.Language;
}
}
return ocrResultDTO;
}
catch
{
ocrResultDTO.DetectedText = "Error occurred. Try again";
ocrResultDTO.Language = "unk";
return ocrResultDTO;
}
}
static async Task<string> ReadTextFromStream(byte[] byteData)
{
try
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
string requestParameters = "language=unk&detectOrientation=true";
string uri = uriBase + "?" + requestParameters;
HttpResponseMessage response;
using (ByteArrayContent content = new ByteArrayContent(byteData))
{
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response = await client.PostAsync(uri, content);
}
string contentString = await response.Content.ReadAsStringAsync();
string result = JToken.Parse(contentString).ToString();
return result;
}
catch (Exception e)
{
return e.Message;
}
}
[HttpGet]
public async Task<List<AvailableLanguageDTO>> GetAvailableLanguages()
{
string endpoint = "https://api.cognitive.microsofttranslator.com/languages?api-version=3.0&scope=translation";
var client = new HttpClient();
using (var request = new HttpRequestMessage())
{
request.Method = HttpMethod.Get;
request.RequestUri = new Uri(endpoint);
var response = await client.SendAsync(request).ConfigureAwait(false);
string result = await response.Content.ReadAsStringAsync();
AvailableLanguage deserializedOutput = JsonConvert.DeserializeObject<AvailableLanguage>(result);
List<AvailableLanguageDTO> availableLanguage = new List<AvailableLanguageDTO>();
foreach (KeyValuePair<string, LanguageDetails> translation in deserializedOutput.Translation)
{
AvailableLanguageDTO language = new AvailableLanguageDTO();
language.LanguageID = translation.Key;
language.LanguageName = translation.Value.Name;
availableLanguage.Add(language);
}
return availableLanguage;
}
}
}
}
فهم وظائف OCRController
في دالة البناء (constructor) للفئة OCRController، قمنا بتهيئة مفتاح الاشتراك (subscriptionKey) وعنوان URL لنقطة النهاية (endpoint URL) الخاصة بواجهة برمجة تطبيقات OCR API. هذه القيم ضرورية للمصادقة والوصول إلى الخدمة.
- التعامل مع طلبات
POST(Postmethod):
تستقبل هذه الدالة بيانات الصورة كـfile collectionفي جسم الطلب (request body) وتُرجع كائنًا من النوعOcrResultDTO. نقوم بتحويل بيانات الصورة إلى مصفوفة بايت (byte array) ثم نستدعي الدالة المساعدةReadTextFromStream. بعد ذلك، نقوم بتحويل الاستجابة إلى كائن من النوعOcrResult. إذا تم اكتشاف اللغة، نقوم بتشكيل الجملة عن طريق التكرار على كائناتOcrWordالمستخرجة. - قراءة النص من تيار البيانات (
ReadTextFromStreammethod):
داخل هذه الدالة، نُنشئ كائنHttpRequestMessageجديدًا. هذا الطلب هو طلبPOST. نمرر مفتاح الاشتراك في ترويسة الطلب (header). ستُرجع واجهة برمجة تطبيقاتOCR APIكائنJSONيحتوي على كل كلمة من الصورة بالإضافة إلى اللغة المكتشفة للنص. - الحصول على اللغات المتاحة (
GetAvailableLanguagesmethod):
تُرجع هذه الدالة قائمة بجميع اللغات المدعومة بواسطة واجهة برمجة تطبيقاتTranslate Text API. نقوم بتعيينURIللطلب وإنشاءHttpRequestMessage، والذي سيكون طلبGET. سيعيدURIهذا طلبJSONيتم تحويله إلى كائن من النوعAvailableLanguage.
لماذا نحتاج إلى جلب قائمة اللغات المدعومة؟
تُرجع واجهة برمجة تطبيقات OCR API رمز اللغة (على سبيل المثال، en للإنجليزية، de للألمانية، إلخ) للغة المكتشفة. ومع ذلك، لا يمكننا عرض رمز اللغة على واجهة المستخدم (UI) لأنه ليس سهل الاستخدام للمستخدمين. لذلك، نحتاج إلى قاموس للبحث عن اسم اللغة المقابل لرمز اللغة.
تدعم واجهة برمجة تطبيقات Azure Computer Vision OCR API عددًا محدودًا من اللغات (25 لغة). لمعرفة جميع اللغات المدعومة بواسطة OCR API، يمكنك الرجوع إلى قائمة اللغات المدعومة. هذه اللغات هي مجموعة فرعية من اللغات المدعومة بواسطة واجهة برمجة تطبيقات Azure Translate Text API.
نظرًا لعدم وجود نقطة نهاية API مخصصة لجلب قائمة اللغات المدعومة بواسطة OCR API، فإننا نستخدم نقطة نهاية Translate Text API لجلب قائمة اللغات. سنقوم بإنشاء قاموس بحث اللغة باستخدام استجابة JSON من استدعاء API هذا وتصفية النتيجة بناءً على رمز اللغة الذي تُرجعه OCR API.
العمل على جانب العميل من التطبيق (Client-side)
يتوفر كود جانب العميل في مجلد ClientApp. سنستخدم Angular CLI للعمل مع كود العميل. استخدام Angular CLI ليس إلزاميًا، ولكنه يسهل العمل ويوفر الوقت. إذا كنت لا ترغب في استخدام CLI، يمكنك إنشاء ملفات المكونات والخدمات يدويًا. انتقل إلى مجلد ngComputerVision\ClientApp في جهازك وافتح نافذة الأوامر. سنقوم بتنفيذ جميع أوامر Angular CLI في هذه النافذة.
إنشاء نماذج جانب العميل (Client-side Models)
أنشئ مجلدًا يسمى models داخل مجلد ClientApp\src\app. الآن سنقوم بإنشاء ملف availablelanguage.ts في مجلد models. ضع الكود التالي فيه:
export class AvailableLanguage {
languageID: string;
languageName: string;
}
وبالمثل، أنشئ ملفًا آخر داخل مجلد models يسمى ocrresult.ts. ضع الكود التالي فيه:
export class OcrResult {
language: string;
detectedText: string
}
يمكنك ملاحظة أن كلتا هاتين الفئتين لهما نفس التعريف مثل فئات DTO التي أنشأناها على جانب الخادم. سيسمح لنا هذا بربط البيانات التي تُرجعها الخادم مباشرة بنماذجنا.
إنشاء خدمة Computervision (Computervision Service)
سنقوم بإنشاء خدمة Angular التي ستستدعي نقاط نهاية Web API، وتحول استجابة Web API إلى JSON وتمررها إلى مكوننا. قم بتشغيل الأمر التالي:
ng g s services\Computervision
سيؤدي هذا الأمر إلى إنشاء مجلد باسم services ثم إنشاء الملفين التاليين بداخله:
computervision.service.ts— ملف فئة الخدمة.computervision.service.spec.ts— ملف اختبار الوحدة للخدمة.
افتح ملف computervision.service.ts وضع الكود التالي بداخله:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ComputervisionService {
baseURL: string;
constructor(private http: HttpClient) {
this.baseURL = '/api/OCR';
}
getAvailableLanguage() {
return this.http.get(this.baseURL)
.pipe(
response => {
return response;
});
}
getTextFromImage(image: FormData) {
return this.http.post(this.baseURL, image)
.pipe(
response => {
return response;
});
}
}
لقد قمنا بتعريف متغير baseURL الذي سيحمل عنوان URL لنقطة نهاية واجهة برمجة التطبيقات الخاصة بنا. سنقوم بتهيئة baseURL في دالة البناء (constructor) وتعيينها لنقطة نهاية OCRController.
- دالة
getAvailableLanguage: سترسل طلبGetإلى دالةGetAvailableLanguagesفيOCRControllerلجلب قائمة اللغات المدعومة لـOCR. - دالة
getTextFromImage: سترسل طلبPostإلىOCRControllerوتوفر المعامل من النوعFormData. ستجلب النص المكتشف من الصورة ورمز اللغة للنص.
إنشاء مكون Ocr (Ocr Component)
قم بتشغيل الأمر التالي في موجه الأوامر لإنشاء OcrComponent:
ng g c ocr -- module app
سيضمن علامة --module أن هذا المكون سيتم تسجيله في app.module.ts.
كود ocr.component.html
افتح ملف ocr.component.html وضع الكود التالي فيه:
<h2>Optical Character Recognition (OCR) using Angular and Azure Computer Vision Cognitive Services</h2>
<div class="row">
<div class="col-md-5">
<textarea disabled class="form-control" rows="10" cols="15">{{ocrResult?.detectedText}}</textarea>
<hr />
<div class="row">
<div class="col-sm-5">
<label><strong>Detected Language :</strong></label>
</div>
<div class="col-sm-6">
<input disabled type="text" class="form-control" value={{DetectedTextLanguage}} />
</div>
</div>
</div>
<div class="col-md-5">
<div class="image-container">
<img class="preview-image" src={{imagePreview}}>
</div>
<input type="file" (change)="uploadImage($event)" />
<p>{{status}}</p>
<hr />
<button [disabled]="loading" class="btn btn-primary btn-lg" (click)="GetText()">
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
Extract Text
</button>
</div>
</div>
لقد قمنا بتعريف منطقة نص (textarea) لعرض النص المكتشف ومربع نص (text box) لعرض اللغة المكتشفة. كما قمنا بتعريف عنصر تحكم لتحميل الملف (file upload control) والذي سيسمح لنا بتحميل صورة. بعد تحميل الصورة، سيتم عرض معاينة الصورة باستخدام عنصر <img>.
كود ocr.component.ts
افتح ملف ocr.component.ts وضع الكود التالي فيه:
import { Component, OnInit } from '@angular/core';
import { ComputervisionService } from '../services/computervision.service';
import { AvailableLanguage } from '../models/availablelanguage';
import { OcrResult } from '../models/ocrresult';
@Component({
selector: 'app-ocr',
templateUrl: './ocr.component.html',
styleUrls: ['./ocr.component.css']
})
export class OcrComponent implements OnInit {
loading = false;
imageFile;
imagePreview;
imageData = new FormData();
availableLanguage: AvailableLanguage[];
DetectedTextLanguage: string;
ocrResult: OcrResult;
DefaultStatus: string;
status: string;
maxFileSize: number;
isValidFile = true;
constructor(private computervisionService: ComputervisionService) {
this.DefaultStatus = "Maximum size allowed for the image is 4 MB";
this.status = this.DefaultStatus;
this.maxFileSize = 4 * 1024 * 1024; // 4MB
}
ngOnInit() {
this.computervisionService.getAvailableLanguage().subscribe(
(result: AvailableLanguage[]) => this.availableLanguage = result
);
}
uploadImage(event) {
this.imageFile = event.target.files[0];
if (this.imageFile.size > this.maxFileSize) {
this.status = `The file size is ${this.imageFile.size} bytes, this is more than the allowed limit of ${this.maxFileSize} bytes.`
this.isValidFile = false;
} else if (this.imageFile.type.indexOf('image') == -1) {
this.status = "Please upload a valid image file";
this.isValidFile = false;
} else {
const reader = new FileReader();
reader.readAsDataURL(event.target.files[0]);
reader.onload = () => {
this.imagePreview = reader.result;
};
this.status = this.DefaultStatus;
this.isValidFile = true;
}
}
GetText() {
if (this.isValidFile) {
this.loading = true;
this.imageData.append('imageFile', this.imageFile);
this.computervisionService.getTextFromImage(this.imageData).subscribe(
(result: OcrResult) => {
this.ocrResult = result;
if (this.availableLanguage.find(x => x.languageID === this.ocrResult.language)) {
this.DetectedTextLanguage = this.availableLanguage.find(x => x.languageID === this.ocrResult.language).languageName;
} else {
this.DetectedTextLanguage = "unknown";
}
this.loading = false;
});
}
}
}
سنقوم بحقن خدمة ComputervisionService في دالة البناء (constructor) الخاصة بـ OcrComponent وتعيين رسالة وقيمة للحد الأقصى لحجم الصورة المسموح به داخل دالة البناء.
- دالة
ngOnInit: سنستدعي دالةgetAvailableLanguageمن خدمتنا فيngOnInitونخزن النتيجة في مصفوفة من النوعAvailableLanguage. - دالة
uploadImage: سيتم استدعاء هذه الدالة عند تحميل صورة. سنتحقق مما إذا كان الملف المحمل صورة صالحة وضمن حد الحجم المسموح به. سنقوم بمعالجة بيانات الصورة باستخدام كائنFileReader. ستقوم دالةreadAsDataURLبقراءة محتويات الملف المحمل. عند الانتهاء بنجاح من عملية القراءة، سيتم تشغيل حدثreader.onload. سيتم تعيين قيمةimagePreviewإلى النتيجة التي يُرجعها كائنfileReader، وهي من النوعArrayBuffer. - دالة
GetText: داخل هذه الدالة، سنقوم بإلحاق ملف الصورة بمتغير من النوعFormData. سنستدعي دالةgetTextFromImageمن الخدمة ونربط النتيجة بكائن من النوعOcrResult. سنبحث عن اسم اللغة من مصفوفةavailableLanguage، بناءً على رمز اللغة الذي تُرجعه الخدمة. إذا لم يتم العثور على رمز اللغة، فسنقوم بتعيين اللغة على أنهاunknown(غير معروفة).
كود ocr.component.css
سنضيف التنسيق لمنطقة النص في ملف ocr.component.css كما هو موضح أدناه:
.preview-image {
max-height: 300px;
max-width: 300px;
}
.image-container {
display: flex;
padding: 15px;
align-content: center;
align-items: center;
justify-content: center;
border: 2px dashed skyblue;
}
إضافة الروابط في قائمة التنقل (Nav Menu)
سنضيف روابط التنقل لمكوناتنا في قائمة التنقل. افتح ملف nav-menu.component.html وقم بإزالة الروابط لمكونات Counter و Fetch data. أضف الأسطر التالية في قائمة روابط التنقل:
<li class="nav-item" [routerLinkActive]="['link-active']">
<a class="nav-link text-dark" routerLink='/computer-vision-ocr'>Computer Vision</a>
</li>
عرض التنفيذ العملي
اضغط على مفتاح F5 لتشغيل التطبيق. انقر على زر Computer Vision في قائمة التنقل العلوية. يمكنك تحميل صورة واستخراج النص منها كما هو موضح في الصورة المتحركة أدناه.

الخلاصة التقنية
لقد نجحنا في بناء تطبيق قارئ أحرف ضوئية (OCR) متكامل يجمع بين مرونة Angular لواجهة المستخدم وقوة Azure Computer Vision Cognitive Service لتحليل الصور. أظهر التطبيق قدرة فائقة على استخراج النصوص المطبوعة من الصور المرفوعة، بالإضافة إلى تحديد اللغة التي كُتب بها النص بدقة. الاعتماد على واجهة برمجة تطبيقات OCR API من Computer Vision، والتي تدعم 25 لغة، يفتح آفاقًا واسعة لتطبيقات معالجة المستندات متعددة اللغات. هذا المشروع يقدم نموذجًا عمليًا لكيفية دمج خدمات الذكاء الاصطناعي السحابية مع أطر عمل الويب الحديثة لإنشاء حلول قوية وفعالة.