با جاوا اسکریپت سلفی بگیرید

گردآوری و تالیف : امیررضا سیستانه ای
تاریخ انتشار : 16 دی 1396
دسته بندی ها : جاوا اسکریپت

در این آموزش می خواهیم به شما نشان بدیم که چطور یک اپلیکیشن عکاسی جاوا اسکریپت بسازید که با استفاده از دوربین گوشی, لپ تاپ یا دسکتاپ عکس بگیره. ما تعدادی از API های بومی فوق العاده رو نمایش میدیم که بهمون اجازه میدن پروژه خودمون رو بدون هیچ وابستگی خارجی (dependencies) بسازیم.

توجه کنید که این اپلیکیشن از تکنولوژی تجربی (experimental) استفاده میکنه که در Safari دسکتاپ و موبایل موجود نیست.

اپلیکیشن

اپلیکیشن ما برای کاربران نهایی فقط نسخه ی ساده ی اپلیکیشن دوربین هست که روی هر موبایلی پیدا میشه. این از سخت افزار دوربین استفاده میکنه تا عکس بگیره - همین. اما در پشت صحنه تعداد زیادی کد جاوا اسکریپت در جریان است تا این اتفاق بیافته. این هم یک نمای کلی :

  • ما به ورودی دوربین دسترسی پیدا کرده و با استفاده از getUserMedia API یک جریان ویدیویی ازش می گیریم.
  • جریان دوربین رو به عنصر video در کد HTML می فرستیم.
  • وقتی کاربر بخواهد عکس بگیرد, ما فریم فعلی ویدیو رو کپی کرده و اون رو در یک عنصر canvas نقاشی می کنیم.
  • اون canvas رو به یک dataURL تصویر تبدیل می کنیم که بتونه روی نمایشگر نشون داده بشه یا به عنوان PNG دانلود بشه.

در این مقاله ما فقط به بخش های جذاب کد می پردازیم. برای دانلود سورس کامل کد از این لینک استفاده کنید یا برای بررسی دمو در JSfiddle اینجا را کلیک کنید.

به یاد داشته باشید که  navigator.getUserMedia به عنوان API منسوخ در نظر گرفته می شود اما این هنوز هم پشتیبانی مرورگرها رو داره و درحال حاضر تنها راه دسترسی به دوربین هست, تا زمانی که جایگزینش یعنی navigator.mediaDevices.getUserMedia بتونه پشتیبانی اکثر مرورگرها رو کسب کنه.

دسترسی به دوربین

جاوا اسکریپت یک API بومی برای دسترسی به هر سخت افزار دوربینی با استفاده از فرم متد navigator.getUserMedia فراهم کرده. از اونجا که این API از اطلاعات شخصی استفاده میکنه, فقط در اتصالات امن HTTPS کار میکنه و همیشه قبل از اقدام از کاربر برای اجازه دسترسی سوال میکنه.

اگر کاربر اجازه بده تا دوربین فعال بشه, navigator.getUserMedia به عنوان callback موفق به ما یک جریان ویدیویی میده. این جریان شامل اطلاعات پخش خام هست که از دوربین میاد و نیاز به تبدیل شدن داره. این تبدیل توسط متد createObjectURL انجام میشه تا جریان ما یک منبع قابل استفاده در رسانه های واقعی بشه.

navigator.getUserMedia(
    // Options
    {
        video: true
    },
    // Success Callback
    function(stream){

        // Create an object URL for the video stream and
        // set it as src of our HTLM video element.
        video.src = window.URL.createObjectURL(stream);

        // Play the video element to show the stream to the user.
        video.play();

    },
    // Error Callback
    function(err){

        // Most common errors are PermissionDenied and DevicesNotFound.
        console.error(err);

    }
);

گرفتن عکس

وقتی که جریان ویدیو رو داریم, ما میتونیم snapshot هایی رو از ورودی دوربین بگیریم. این کار با یک ترفند جالب انجام میشه که عنصر قدرتمند canvas رو برای گرفتن یک فریم از جریان ویدیویی در حال اجرا استفاده میکنه و اون رو به عنوان یک عنصر img ذخیره میکنه.

function takeSnapshot(){

    var hidden_canvas = document.querySelector('canvas'),
        video = document.querySelector('video.camera_stream'),
        image = document.querySelector('img.photo'),

        // Get the exact size of the video element.
        width = video.videoWidth,
        height = video.videoHeight,

        // Context object for working with the canvas.
        context = hidden_canvas.getContext('2d');

    // Set the canvas to the same dimensions as the video.
    hidden_canvas.width = width;
    hidden_canvas.height = height;

    // Draw a copy of the current frame from the video on the canvas.
    context.drawImage(video, 0, 0, width, height);

    // Get an image dataURL from the canvas.
    var imageDataURL = hidden_canvas.toDataURL('image/png');

    // Set the dataURL as source of an image element, showing the captured photo.
    image.setAttribute('src', imageDataURL); 

}

خود عنصر canvas لازم نیست حتی در DOM نمایان بشه. ما فقط از API جاوا اسکریپت برای یافتن راهی برای ضبط لحظه ای از ویدیو استفاده می کنیم. 

دانلود عکس

قطعا ما نمی خواهیم فقط سلفی بگیریم, بلکه می خواهیم قادر باشیم عکس رو ذخیره کنیم و داشته باشیم. ساده ترین راه برای انجام این کار استفاده از صفت download در عناصر <a> هست. در کد HTML دکمه به صورت زیر نمایش داده میشه :

<a id="dl-btn" href="#" download="glorious_selfie.png">Save Photo</a>

صفت download لینک ما رو تبدیل به یک لینک دانلود میکنه. مقدار اون نشان دهنده ی نام پیش فرض فایل دانلودی هست, فایل حقیقی که دانلود میشه در صفت href قرار داده میشه, همینطور که می بینید فعلا خالی هست. برای اینکه آخرین عکس گرفته شده رو بارگذاری کنیم, ما میتونیم از dataURL در بخش قبلی استفاده کنیم :

function takeSnapshot(){

    //...

    // Get an image dataURL from the canvas.
    var imageDataURL = hidden_canvas.toDataURL('image/png');

    // Set the href attribute of the download button.
    document.querySelector('#dl-btn').href = imageDataURL;
}

حالا وقتی کسی روی دکمه کلیک کنه, فایلی با نام glorious_selfie.png دانلود میکنه که شامل عکس گرفته شده ی ماست. با این کار تجربه کوچک ما کامل میشه.

منبع

مقالات پیشنهادی

دسترسی به کلیپ بورد با جاوا اسکریپت

ویژگی شگفت انگیزی که شما میتوانید به وبسایت خود اضافه کنید ، کپی کردن یک رشته با عمل کلیک بر روی یک Button است . این تعامل میتواند در کپی کردن Url ها...

تبدیل صدا به متن با جاوا اسکریپت

در این آموزش میخواهیم کار با Web Speech API رو تجربه کنیم. این یکی از قدرتمندترین رابط های مرورگریست که به شما اجازه میده صدای انسان رو ضبط کرده و به...

دیباگ پروژه های جاوا اسکریپت با استفاده از Source Map ها

امروزه، کدی که برای برنامه خود می نویسید معمولا همان کدی نیست که در هنگام تولید استفاده می شود و توسط مرورگر ترجمه می شود. شاید کد خود را با زبانی می...

موقعیت یابی جغرافیایی با جاوا اسکریپت

اکثر دستگاه های مدرن میتوانند مکان جغرافیایی خودشون رو توسط GPS, Wifi یا موقعیت آیپی شناسایی کنند. توسعه دهندگان با استفاده از این اطلاعات میتونند برا...