html5調用手機相機並壓縮、上傳


使用input file[camera]屬性調用相機

簡直So easy!

<input type="file" accept="image/*;" capture="camera" >

 

只需要這么一條簡單的代碼,在手機瀏覽器點擊就可以打開相機了。

capture是什么?其實就是對打開方式的設置。

 

<!-- capture=camcorder,調用手機攝像功能 -->
<input type="file" accept="video/*" capture="camcorder" >
<!-- capture=microphone,調用手機錄音功能 -->
<input type="file" accept="audio/*" capture="microphone" >

 

 

魅族MX5測試結果:

  • 谷歌瀏覽器可以打開相機和攝像功能,其他方式均為相機、圖庫、文件管理器等混合選擇項。
  • 自帶瀏覽器打開均為文件管理器。

由此說明此屬性兼容性還是個問題。不過這並不能阻止我繼續折騰下去!

 

 

圖片壓縮

在如今這個手機普遍千萬像素的時代,一張照片動輒5M的大小。作為一個良心的開發者,我們是要為用戶的流量負責的。
該怎么做?我也不知道。大家都在用canvas實現,我也就用了。

 

document.getElementById('file').addEventListener('change', function() {
    var reader = new FileReader();
    reader.onload = function (e) {
        compress(this.result);
    };
    reader.readAsDataURL(this.files[0]);
}, false);

 

不管文件域是用何種方式打開的,都可以在 change 事件中獲取到選擇的文件或拍攝的照片。

創建一個FileReader對象,我們需要調用readAsDataURL把文件轉換為base64圖像編碼,如data:image/jpeg;base64……這種格式。
onload是一個異步回調,當文件讀取完執行該方法內代碼。this.result記錄讀取結果,如果讀取失敗,該值為null。在這里進行圖片壓縮的具體操作。

 

var compress = function (res) {
    var img = new Image(),
        maxH = 160;
    img.onload = function () {
        var cvs = document.createElement('canvas'),
            ctx = cvs.getContext('2d');
        if(img.height > maxH) {
            img.width *= maxH / img.height;
            img.height = maxH;
        }
        cvs.width = img.width;
        cvs.height = img.height;
        ctx.clearRect(0, 0, cvs.width, cvs.height);
        ctx.drawImage(img, 0, 0, img.width, img.height);
        var dataUrl = cvs.toDataURL('image/jpeg', 0.6);
        // 上傳略
    }
    img.src = res;
}

 

 

創建一個Image對象,給src屬性賦值為讀取結果,同樣在onload異步回調中編寫處理圖片的代碼。
這里就要開始使用canvas進行圖片壓縮了。

首先是尺寸按比例縮放,然后把圖片繪到畫布上,最后調用toDataURL方法壓縮圖像質量。

 

context.toDataURL('MIME類型', 圖像質量0-1);  // 該方法返回base64圖像編碼

 

代碼里省略了一些校監操作,如文件類型約束和文件大小判斷(小於一定值可以不壓縮)。
最后就是把數據發送到后端的操作,這里就不說了。

 

Html5調用攝像頭

通過以上的代碼已經可以實現調用手機相機拍照、壓縮、上傳這一整套流程了。
不過在折騰的過程中也發現了一種調用攝像頭的方法。注意,是攝像頭!使用input調用的是相機。其中的差別就是攝像頭是只捕獲畫面,相機還包括原生的一些拍照、設置等控件。

通過對攝像頭的調用可以做很多有趣的事,比如拍照美化、濾鏡等。可以說實現一個第三方相機是沒問題的。
之前下載過一款安卓相機APP,不到100K的大小,可以實現拍照的一些風格化,也許就是Html5實現的呢。

需要用到的是 getUserMedia API,具體的實現這里就不貼了。

【用到的HTML5標簽】

 

<input type="file" capture="camera" accept="image/*" id="cameraInput" name="cameraInput" class="sign_file"/>

 

【等比縮放圖片】

 

function drawOnCanvas(file) {
    var reader = new FileReader();
    reader.onload = function(e) {
        var dataURL = e.target.result,
        canvas = document.querySelector('canvas'),
        ctx = canvas.getContext('2d'),
        img = new Image();
        img.onload = function() {
            var square = 320;
            canvas.width = square;
            canvas.height = square;
            var context = canvas.getContext('2d');
            context.clearRect(0, 0, square, square);
            var imageWidth;
            var imageHeight;
            var offsetX = 0;
            var offsetY = 0;
            if (this.width > this.height) {
                imageWidth = Math.round(square * this.width / this.height);
                imageHeight = square;
                offsetX = -Math.round((imageWidth - square) / 2);
            } else {
                imageHeight = Math.round(square * this.height / this.width);
                imageWidth = square;
                offsetY = -Math.round((imageHeight - square) / 2);
            }
            context.drawImage(this, offsetX, offsetY, imageWidth, imageHeight);
            var base64 = canvas.toDataURL('image/jpeg', 0.5);
            $('#j_thumb').val(base64.substr(22));
        };
        img.src = dataURL;
    };
    reader.readAsDataURL(file);
}

 

FileReader對象是用來解析file控件獲取的本地圖片地址的,具體介紹請百度一下。把解析好的地址設置給IMG標簽的SRC屬性,然后通過canvas對象把圖片繪制; 在這過程中就有個等比縮放的算法,再用drawImage方法把圖像畫到canvas中。
【如何獲取畫好的圖片數據傳到后端處理】
通過 canvas.toDataURL(‘image/jpeg’,0.5)就可以獲取到base64編碼值,然后你就可以按照傳統的POST或者AJAX方式處理了。

【讓圖片顯示】

document.querySelector('input[type=file]').onchange = function() {
    var file = input.files[0];
    drawOnCanvas(file);
};

 

【后台處理方式】

$base64 = $_POST['formFile'];
$IMG = base64_decode( $base64 );
file_put_contents('1.png', $IMG );
根傳統的上傳圖片不同,這時候后台需要用base64_decode解碼

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM