小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

HTML5裁剪圖片并上傳至服務(wù)器實現(xiàn)原理講解

 米老鼠的世界 2021-02-03
經(jīng)常做項目需要本地上傳圖片裁剪并上傳服務(wù)器,比如會議頭像等功能,但以前實現(xiàn)這類需求都很復(fù)雜,往往需要先把圖片上傳到服務(wù)器,然后返回給用戶,讓用戶確定裁剪坐標(biāo),發(fā)送給服務(wù)器,服務(wù)器裁剪完再返回給用戶,來回需要 5 步。步驟繁瑣不說,當(dāng)很多用戶上傳圖片的時候也很影響服務(wù)器性能。

第一步:獲取文件

HTML5 支持從 input[type=file] 元素中直接獲取文件信息,也可以讀取文件內(nèi)容。我們用下面代碼就可以實現(xiàn):

$('input[type=file]').change(function(){
    var file=this.files[0];
    // continue ...
});

第二部:讀取文件,并生成 Image 元素

這一步就需要用到 FileReader 了,這個類是專門用來讀取本地文件的。純文本或者二進(jìn)制都可以讀取,但是本地文件必須是經(jīng)過用戶允許才能讀取,也就是說用戶要在input[type=file]中選擇了這個文件,你才能讀取到它。

通過 FileReader 我們可以將圖片文件轉(zhuǎn)化成 DataURL,就是以 data:image/png;base64, 開頭的一種URL,然后可以直接放在 image.src 里,這樣本地圖片就顯示出來了。

$('input[type=file]').change(function(){
    var file=this.files[0];

    var reader=new FileReader();
    reader.onload=function(){
        // 通過 reader.result 來訪問生成的 DataURL
        var url=reader.result;
        setImageURL(url);
    };
    reader.readAsDataURL(file);
});

var image=new Image();
function setImageURL(url){
    image.src=url;
}

Image 就是在 html 里的 <img> 標(biāo)簽,所以可以直接插入到文檔流里。

第三步:獲取裁剪坐標(biāo)

這一步?jīng)]啥好說的,實現(xiàn)的方法也很多,需要獲得下面四個裁剪框的坐標(biāo):

  • Y坐標(biāo)
  • X坐標(biāo)
  • 高度
  • 寬度

如下圖所示:

第四部:裁剪圖片

這是時候我們就需要用到 canvas 了,canvas 和圖片一樣,所以新建 canvas 時就要確定其高寬。這里我們還運用到image.naturalHeight 和 image.naturalWidth 這兩個屬性來獲取圖片原始尺寸。

將圖片放置入 canvas 時需要調(diào)用 drawImage ,這個接口參數(shù)比較多,在 MDN 上有詳細(xì)的說明。

drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)

因為我們用 canvas 只是用于裁剪圖片的,所以需要新建一個 canvas 讓它的尺寸和裁剪之后圖片的尺寸相等,此時canvas 就相當(dāng)與我們的裁剪框。運用這個函數(shù)還可以將大圖縮放成小圖,同學(xué)們自己研究吧。

// 以下四個參數(shù)由第三步獲得
var x,  
    y,
    width,
    height;

var canvas=$('<canvas width="'+width+'" height="'+height+'"></canvas>')[0],
    ctx=canvas.getContext('2d');

ctx.drawImage(image,x,y,width,height,0,0,width,height);
$(document.body).append(canvas);

將 canvas 加入文檔流之后,就可以看到裁剪后的效果了。不過我們還需要將圖片上傳至服務(wù)器里。

第五步:讀取裁剪后的圖片并上傳

這時我們要獲取 canvas 中圖片的信息,用 toDataURL 就可以轉(zhuǎn)換成上面用到的 DataURL 。 然后取出其中 base64 信息,再用 window.atob 轉(zhuǎn)換成由二進(jìn)制字符串。但 window.atob 轉(zhuǎn)換后的結(jié)果仍然是字符串,直接給 Blob 還是會出錯。所以又要用 Uint8Array 轉(zhuǎn)換一下??傊@里挺麻煩的。。

var data=canvas.toDataURL();

// dataURL 的格式為 “data:image/png;base64,****”,逗號之前都是一些說明性的文字,我們只需要逗號之后的就行了
data=data.split(',')[1];
data=window.atob(data);
var ia = new Uint8Array(data.length);
for (var i = 0; i < data.length; i++) {
    ia[i] = data.charCodeAt(i);
};

// canvas.toDataURL 返回的默認(rèn)格式就是 image/png
var blob=new Blob([ia], {type:"image/png"});

這時候裁剪后的文件就儲存在 blob 里了,我們可以把它當(dāng)作是普通文件一樣,加入到 FormData 里,并上傳至服務(wù)器了。

FormData 顧名思義,就是用來創(chuàng)建表單數(shù)據(jù)的,用 append 以鍵值的形式將數(shù)據(jù)加入進(jìn)去即可。但他最大的特點就是可以手工添加文件或者 Blob 類型的數(shù)據(jù),Blob 數(shù)據(jù)也會被當(dāng)作文件來處理。原生 js 可以直接傳遞給 xhr.send(fd), jquery 可以放入 data 里請求。

var fd=new FormData();

fd.append('file',blob);
$.ajax({
    url:"your.server.com",
    type:"POST",
    data:fd,
    success:function(){}
});

然后你服務(wù)器里應(yīng)該就可以收到這個文件了~

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多