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