圖片上傳縮略圖預覽

在上傳圖片進行預覽時,直接抓取原圖時因爲原圖過大會影響性能,即對所上傳圖片進行壓縮小圖展現;canvas

思路: 利用 canvas 對原圖進行壓縮重繪,抓取區域以中心爲基點最大範圍繪製縮略圖;數組

對input[file]進行事件綁定

// 監控 file 變化
imgfile.addEventListener('change', function () {
    ...
}

利用 FileReader 讀取上傳的圖片

var reader = new FileReader()
reader.onload = function () {
    ...
}
reader.readAsDataURL(file);

建立 canvas、image,並獲取寬高

var canvas = document.createElement('canvas');
// 設置 canvas 畫布大小
canvas.width = thumbnailWidth, 
canvas.height = thumbnailHeight;

var ctx = canvas.getContext("2d");
var thumbnailItem = new Image();

//獲取圖片寬高
thumbnailItem.onload = function () {
    var imgWidth = this.width,
        imgHeight = this.height,
        drawWidth = '',
        drawHeight = '',
        dx,
        dy;
}

對原圖進行寬高分析,最大化展現原圖區域

// 判斷原圖寬高
if (imgWidth > imgHeight) {
    drawWidth = drawHeight = imgHeight;
    dx = (imgWidth - imgHeight) / 2, dy = 0
} else {
    drawWidth = drawHeight = imgWidth;
    dx = 0, dy = (imgHeight - imgWidth) / 2
}

進行繪製縮略圖

//void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

ctx.drawImage(thumbnailItem, dx, dy, drawWidth, drawHeight, 0, 0, thumbnailWidth, thumbnailHeight)

//dx
//目標畫布的左上角在目標canvas上 X 軸的位置。
//dy
//目標畫布的左上角在目標canvas上 Y 軸的位置。
//dWidth
//在目標畫布上繪製圖像的寬度。 容許對繪製的圖像進行縮放。 若是不說明, 在繪製時圖片寬度不//會縮放。
//dHeight
//在目標畫布上繪製圖像的高度。 容許對繪製的圖像進行縮放。 若是不說明, 在繪製時圖片高度不//會縮放。
//sx
//須要繪製到目標上下文中的,源圖像的矩形選擇框的左上角 X 座標。
//sy
//須要繪製到目標上下文中的,源圖像的矩形選擇框的左上角 Y 座標。
//sWidth
//須要繪製到目標上下文中的,源圖像的矩形選擇框的寬度。若是不說明,整個矩形從座標的sx和sy開//始,到圖像的右下角結束。
//sHeight
//須要繪製到目標上下文中的,源圖像的矩形選擇框的高度。

生成base64

// 生成base64
dataUrl = canvas.toDataURL()

核心代碼

// 監控 file 變化
imgfile.addEventListener('change', function () {

    if (!this.files.length) return;

    var files = Array.prototype.slice.call(this.files);

    if (files.length > maxQuantity) {
        alert("最多同時只可上傳100張圖片");
        return;
    }

    files.forEach(function (file, i) {

        var reader = new FileReader(),
            dataUrl = '';
        reader.onload = function () {
            var canvas = document.createElement('canvas');
            // 設置 canvas 畫布大小
            canvas.width = thumbnailWidth, canvas.height = thumbnailHeight;

            var ctx = canvas.getContext("2d");
            var thumbnailItem = new Image();

            // 添加原圖 url 至數組
            // imgUrls.push(this.result);
            imgUrls[i] = this.result
            thumbnailItem.onload = function () {
                var imgWidth = this.width,
                    imgHeight = this.height,
                    drawWidth = '',
                    drawHeight = '',
                    dx,
                    dy;
                // 判斷原圖寬高
                if (imgWidth > imgHeight) {
                    drawWidth = drawHeight = imgHeight;
                    dx = (imgWidth - imgHeight) / 2, dy = 0
                } else {
                    drawWidth = drawHeight = imgWidth;
                    dx = 0, dy = (imgHeight - imgWidth) / 2
                }

                // console.log('dx :' + dx, 'dy: ' + dy, 'drawWidth :' + drawWidth, 'thumbnailWidth :' + thumbnailWidth, 'thumbnailHeight :' + thumbnailHeight)
                ctx.drawImage(thumbnailItem, dx, dy, drawWidth, drawHeight, 0, 0, thumbnailWidth, thumbnailHeight)

                // 生成base64
                dataUrl = canvas.toDataURL()

                // thumbnaiUrls.push(dataUrl)
                thumbnaiUrls[i] = dataUrl
                var imglist =
                    '<div class="sn-file-item sn-thumbnail">' +
                    '<input type="checkbox" name="sel" class="sn-thumbnail-sel">' +
                    '<img  src=' + dataUrl + ' data-index=' + i + '>' +
                    '<div class="sn-thumbnail-hidebar"><span class="am-icon-trash js-thumbnail-del" data-index=' + i + ' data-name = "del"></span></div>' +
                    '</div>';

                $('#imgList').append(imglist)

            }

            thumbnailItem.src = this.result

            console.log('縮略圖')
            console.log(thumbnaiUrls)

            console.log('原圖')
            console.log(imgUrls)

        };
        reader.readAsDataURL(file);
    })
    
})

總結

須要注意 drawImage 須要放在 onload 的回調函數裏面,避免圖片還未加載完成被繪製出來,即出現圖片一片空白;app

若有錯誤或不足,歡迎指出ide

相關文章
相關標籤/搜索