摘要:需求就是那么簡單,在瀏覽器里裁剪圖片并上傳到服務(wù)器。原圖片對(duì)象上傳裁剪后的對(duì)象初始化圖片預(yù)覽根據(jù)裁剪參數(shù)繪制轉(zhuǎn)對(duì)象以下將對(duì)每個(gè)環(huán)節(jié)詳解。或者根據(jù)獲取裁剪信息包括旋轉(zhuǎn)和縮放用進(jìn)行手動(dòng)繪制。
前言
圖片裁剪上傳,不僅是一個(gè)很貼合用戶體驗(yàn)的功能,還能夠統(tǒng)一特定圖片尺寸,優(yōu)化網(wǎng)站排版,一箭雙雕。
需求就是那么簡單,在瀏覽器里裁剪圖片并上傳到服務(wù)器。
我第一個(gè)想到的方法就是,將圖片和裁剪參數(shù)(x,y,scale,rotate)一并上傳給服務(wù)器,服務(wù)器來做圖片處理,so easy。
但是,這并不符合潮流發(fā)展的方向:能在前端做的處理,就放前端做吧。
與潮流妥協(xié)的結(jié)果就是,前端越來越復(fù)雜。
一開始我并不認(rèn)為瀏覽器能夠讀取并生成圖片。想想看啊,要做"點(diǎn)擊復(fù)制"的這樣簡單的功能,都需要借助 Flash 的瀏覽器,權(quán)限哪有那么大。
參閱各類網(wǎng)站,只要把圖片放在本地處理的,基本上都借用了Flash。隨便抄一個(gè)吧,沒有API,就算能修改圖片,上傳路徑都不知道怎么改。更關(guān)鍵的是,我對(duì)Flash一竅不通。
好在我們的網(wǎng)站已經(jīng)完全拋棄了IE9以下的瀏覽器,只兼容現(xiàn)代HTML5瀏覽器。(連Opera和微軟都開始走Webkit內(nèi)核的路線了,潮流就是跟著Chrome走)只能寄希望與HTML5,于是鉆研了一番,發(fā)現(xiàn)如下流程可行。
st=>start: 原圖片 File 對(duì)象 e=>end: 上傳裁剪后的Blob對(duì)象 op=>operation: 初始化Cropper 圖片Base64預(yù)覽 op1=>operation: 根據(jù)Cropper裁剪參數(shù)繪制Canvas(Base64) op2=>operation: Base64轉(zhuǎn)Blob對(duì)象 st->op->op1->op2->e
以下將對(duì)每個(gè)環(huán)節(jié)詳解。
獲取原圖片 File 對(duì)象每個(gè)圖片文件處理的開始,都是由onchange事件開始
初始化Cropper![]()
在這里介紹一個(gè)非常好用的庫 cropper.js
https://github.com/fengyuanchen/cropper
生成遮罩、獲取裁剪參數(shù)、輸出canvas ... 而且絕對(duì)輕量級(jí),壓縮后的css和js代碼只有30KB。他是基于JQuery的,引入JQuery可能還要再大點(diǎn)。不過現(xiàn)在哪個(gè)網(wǎng)站沒有在用JQuery呢?
兼容IE9+,移動(dòng)端體驗(yàn)良好,能夠響應(yīng)觸摸縮放,拖動(dòng)。以下是安卓4.4 原生瀏覽器中的預(yù)覽圖
function handler(event){ ... var URL = window.URL || window.webkitURL , originPhotoURL; originPhotoURL = URL.createObjectURL(originPhoto); //Base64 $("#preview").cropper({ aspectRatio: 1 / 1, // 固定裁剪比例1:1,裁剪后的圖片為正方形 }).cropper("replace", originPhotoURL); // 動(dòng)態(tài)設(shè)置圖片預(yù)覽 }繪制Canvas
cropper.js 提供了生成Canvas的方法getCroppedCanvas,可以指定生成畫布的大小。
或者根據(jù)getData獲取裁剪信息(包括旋轉(zhuǎn)和縮放)用ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)進(jìn)行手動(dòng)繪制。后者自由性高一點(diǎn),但是既然有現(xiàn)成的方法,那么就直接用好了。
function cropAndUpload(){ // 此處注意,生成的Canvas長寬比應(yīng)與之前規(guī)定的裁剪比例一致 // 否則生成的圖片會(huì)有失真 var size = { width:100, height:100 } var croppedCanvas = $("#preview").cropper("getCroppedCanvas",size); // 生成 canvas 對(duì)象 var croppedCanvasUrl = croppedCanvas.toDataURL(originFileType); // Base64 ... }
應(yīng)當(dāng)注意的是width和height的值并不推薦設(shè)置成固定值。裁剪框的大小可能是會(huì)超過100100(比如500500)的,而實(shí)際生成的圖片卻是100100,這樣的后果就是直接將一個(gè)500500的高清圖片,壓縮成了100100的失真圖片。同樣的,裁剪框小于100100,生成的圖片就會(huì)模糊。
Base64 轉(zhuǎn)Blob對(duì)象字符串轉(zhuǎn)為二進(jìn)制?(前端本來是個(gè)做頁面的,現(xiàn)在也開始操作文件了。自從有了HTML5,就可以把瀏覽器當(dāng)作一個(gè)操作系統(tǒng)了)官方并沒有出DataURLtoBlob的方法,所以只能自己寫一個(gè),轉(zhuǎn)化也挺簡單:拆解文件類型,將字符數(shù)據(jù)轉(zhuǎn)成16進(jìn)制數(shù)據(jù)存數(shù)組,并用數(shù)據(jù)初始化一個(gè)Blob對(duì)象。
function dataURLtoBlob(dataurl) { var arr = dataurl.split(","), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while(n--){ u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], {type:mime}); } function cropAndUpload(){ ... var croppedBlob = dataURLtoBlob(croppedCanvasUrl); croppedBlob.name = originFileName; // Blob對(duì)象沒有name // Upload(croppedBlob); }
現(xiàn)在就可以像處理FileObject一樣處理 這個(gè)blob對(duì)象了。
其實(shí)在最新的HTML5標(biāo)準(zhǔn)中是支持HTMLCanvasElement.toBlob(callback, mimeType, quality) 的
croppedCanvas.toBlob(function(croppedBlob){ // Upload(croppedBlob); },originFileType)
繞了一個(gè)彎,不過還是學(xué)到了東西。
原文作者來自 MaxLeap 團(tuán)隊(duì)_UX成員:John王
原文鏈接:https://blog.maxleap.cn/archives/705
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/79420.html
摘要:比如就會(huì)報(bào)出警告,并執(zhí)行出錯(cuò)。視頻的寬高,并不會(huì)因?yàn)樘顚懙臄?shù)值比例不合法而失真。通過綁定事件,來獲取視頻片段數(shù)據(jù),并在內(nèi)存中累積。執(zhí)行之后會(huì)停止觸發(fā)事件。錄制結(jié)束后,把累計(jì)的片段數(shù)據(jù)保存為對(duì)象,并從瀏覽器下載存為視頻文件。 前言 HTML5的權(quán)限越來越大了,瀏覽器可以直接調(diào)用攝像頭、麥克風(fēng)了,好激動(dòng)啊。我們要用純潔的HTML代碼造出自己的天地。 視頻采集 本篇介紹的栗子 都是在chro...
摘要:一些瀏覽器支持嵌套媒體查詢,例如,和但是和目前并沒有支持嵌套媒體查詢。因此,一方面,我們有一個(gè)斷點(diǎn)管理器從斷點(diǎn)的全局中選擇并處理錯(cuò)誤消息,另一方面有一個(gè)斷點(diǎn)管理器允許使用多查詢條件。 如果你對(duì) Sass不太熟悉的話,你可能不知道Sass增加了許多非常有趣的功能,例如媒體查詢(即 @media)功能(經(jīng)常被成為 Media Merging媒體合并)。 showImg(https://se...
閱讀 2407·2021-11-24 09:39
閱讀 3120·2021-10-15 09:39
閱讀 3173·2021-07-26 23:38
閱讀 2365·2019-08-30 11:14
閱讀 3465·2019-08-29 16:39
閱讀 1762·2019-08-29 15:23
閱讀 865·2019-08-29 13:01
閱讀 2728·2019-08-29 12:29