هدف ما از این مقاله این است که از طریق وب کم، تصاویر را ضبط کنیم (یک نمونه ). برای انجام این کار فایل app.component.html را باز کرده و مطابق زیر ویرایش کنید:
کدهای HTML زیادی در اینجا وجود ندارند. به تگ <video> و <canvas> توجه کنید. برای هر کدام از این تگها، یک local variable وجود دارد که با سمبل # مشخص شدهاند. به عبارت دیگر، دو متغیر video# و canvas# وجود دارند . این گونه است که ما میتوانیم به این المنتها، در کدهای تایپ اسکریپت دسترسی داشته باشیم.
<div id="app"><div><video #video id="video" width="640" height="480" autoplay></video></div><div><button id="snap" (click)="capture()">ضبط تصویر</button></div><canvas #canvas id="canvas" width="640" height="480"></canvas><ul><li *ngFor="let capture of captures"><img src="{{ capture }}" height="50" /></li></ul></div>
المنت <button>، در رویداد کلیک آن، متد capture را فراخوانی میکند که کارش ضبط تصویر میباشد.
و در پایان یک حلقه بر روی آرایهی captures داریم که کارش نمایش تصاویر ضبط شده است. چون هر بار که بر روی دکمه ضبط تصویر کلیک کنیم، یک تصویر به آرایهی captures اضافه میشود .
فایل app.component.ts :
export class AppComponent implements OnInit, AfterViewInit { @ViewChild('video') public video: ElementRef; @ViewChild('canvas') public canvas: ElementRef; public captures: Array<any>; public constructor() { this.captures = []; } public ngOnInit() { } public capture() { this.canvas.nativeElement.getContext('2d').drawImage(this.video.nativeElement, 0, 0, 640, 480); this.captures.push(this.canvas.nativeElement.toDataURL('image/png')); } public ngAfterViewInit() { if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.getUserMedia({ video: true }).then(stream => { this.video.nativeElement.src = window.URL.createObjectURL(stream); this.video.nativeElement.play(); }); } } }
توضیحات :
با استفاده از local variable هایی که در کدهای HTML تعریف کردیم و ViewChild@، میتوانیم المنتها را در متغیرها، load کنیم. در این حالت این امکان وجود دارد تا المنتهای DOM را دستکاری کنیم.ngAfterViewInit ( مربوط به چرخه حیات کامپوننتها میباشد. تعدادی life cycle hook طراحی شده است که یکی از آنها AfterViewInit میباشد و برای استفاده از این hook نیاز است اینترفیس آن را پیاده سازی کنیم ) : بعد از اینکه المنتها در ویو مقدار دهی اولیه شدند، ngAfterViewInit فراخوانی میشود.
public ngAfterViewInit() { if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.getUserMedia({ video: true }).then(stream => { this.video.nativeElement.src = window.URL.createObjectURL(stream); this.video.nativeElement.play(); }); } }
- MediaDevices: این اینترفیس دستیابی به دستگاههای ورودی متصل شده، مثلا دوربین، میکروفن و ... را فراهم میسازد.
- MediaDevices.getUserMedia: با گرفتن مجوزی از کاربر از طریق یک هشدار، دوربین کاربر را روشن میکند و هم چنین این متد یک promise را بازگشت میدهد؛ در صورتیکه کاربر اجازه دسترسی بدهد.
- URL.createObjectURL: یک URL را برای یک BLOB مشخص شده ایجاد میکند (BLOB: Binary large object) که میتواند به متدی که انتظار یک URL را دارد، پاس داده شود. بعد از برگشت URL، متد ()revokeObjectURL فراخوانی میشود که کارش آزاد سازی منابع مرتبط با url ایجاد شدهی توسط createObjectURL میباشد. در ضمن طول عمر url ایجاد شده برابر با بستن سند (document) در پنجرهای (window) که در آن ایجاد شدهاست، میباشد.
عملیات ضبط تصویر در این متد انجام میشود:
public capture() { this.canvas.nativeElement.getContext('2d').drawImage(this.video.nativeElement, 0, 0, 640, 480); this.captures.push(this.canvas.nativeElement.toDataURL('image/png')); }
- ()getContext: این متد یک شیء را برگشت میدهد که فراهم کنندهی متدها و خصوصیتها، برای رسم در Canvas میباشد.
- ()drawImage: این متددر Canvas رسم را انجام میدهد و همچنین این متد میتواند بخشهایی از یک تصویر را رسم کند یا سایز یک تصویر را افزایش یا کاهش دهد.
- ()toDataURL: این متد یک data URI را بازگشت میدهد که یک تصویر در فرمت مشخص شده را بر اساس پارامتر type، برگشت میدهد (پیش فرض آن png میباشد).
تمام !