UNPKG

img-about

Version:

A module for image processing in browser, includes getting naturalSize, zooming, compressing... wrapped by Promise

173 lines (148 loc) 5.84 kB
/** * Bundle of img-about * Generated: 2019-07-23 * Version: 2.2.0 * License: MIT * Author: livelybone(2631541504@qq.com) */ import { blobToBase64, base64ToBlob } from 'base64-blob'; /* global Promise */ /** * @param { String } url * @return { Promise } * */ function getSizeOfUrl(url) { return new Promise(function (res, rej) { var img = document.createElement('img'); var loaded = function () { res({ width: img.width, height: img.height }); }; img.onload = loaded; img.onerror = function () { rej(new Error('Image<' + url + '> loaded error')); }; img.src = url; if (img.complete) loaded(); }) } /** * Whether the canvas is available in current browser * */ var canvasSupport = (function () { var canvas = document.createElement('canvas'); return !!canvas.getContext })(); /* global Promise */ /** * @param { String|Image|File|FileList|Blob } img * @return { Promise } * */ function getNaturalSize(img) { return new Promise(function (res, rej) { if (typeof img === 'string') { res(getSizeOfUrl(img)); } else if (img instanceof Image) { if (img.naturalWidth) { res({ width: img.naturalWidth, height: img.naturalHeight }); } else { res(getSizeOfUrl(img.src)); } } else if ( img instanceof FileList || img instanceof File || img instanceof Blob ) { var f = img[0] || img; res(getSizeOfUrl(blobToBase64(f))); } else { rej(new Error( 'The type of param `img` is not matched.' + ' It should be an instance of one of the String, Image, File, FileList and Blob' )); } }) } /* global Promise */ /** * @param { File|Blob } imgFile * @param { Object } [compressOptions] * @param { String } compressOptions.compressType default to 'scale' * @param { Number } compressOptions.scale default to 1 * @param { Number } compressOptions.imageSize default to 0 * @param { String } compressOptions.imageType default to the type of `imgFile` or 'image/png' * @param { Number } compressOptions.quality default to 0.8 * @param { Boolean } compressOptions.toBlob default to true * @return { Promise } * */ function imgCompress(imgFile, compressOptions) { if (!canvasSupport) { return Promise.reject(new Error('Canvas is not supported in your browser')) } if (!(imgFile instanceof File || imgFile instanceof Blob)) { return Promise.reject(new Error( 'The type of param `imgFile` is not matched' + ' It should be an instance of one of the File and Blob' )) } var compressTypes = [ 'scale', // Resize the image by `options.scale` 'fixedWidth', // Set the width of the image to a fixed value -- `options.imageSize` 'fixedHeight', // Set the height of the image to a fixed value -- `options.imageSize` 'fixedSize', // Set the smaller between width and height of the image to a fixed value -- `options.imageSize` ]; var defaultOptions = { compressType: compressTypes[0], // Compress type, options: `compressTypes` scale: 1, // Scale factor, works when compressType is `scale` imageSize: 0, // The fixed value of size, works when compressType is `fixedWidth`, `fixedHeight` or `fixedSize`. If imageSize is 0, it means convert to naturalSize imageType: imgFile.type || 'image/png', // The mine type of image returned quality: .8, // Compress quality, works when imageType is `image/jpeg` or `image/webp` toBlob: true, // If it is false, the promise returned will be resolved with a base64 string }; var options = defaultOptions; // Merge options if (compressOptions) { Object.keys(defaultOptions).forEach(function (key) { options[key] = compressOptions[key] !== undefined ? compressOptions[key] : defaultOptions[key]; }); } return blobToBase64(imgFile) .then(function (url) { var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); return getNaturalSize(url) .then(function (size) { var width = size.width; var height = size.height; var cWidth, cHeight; // Calculate `cWidth`, `cHeight` if (options.compressType === compressTypes[1]) { cWidth = options.imageSize || width; cHeight = cWidth * height / width; } else if (options.compressType === compressTypes[2]) { cHeight = options.imageSize || height; cWidth = cHeight * width / height; } else if (options.compressType === compressTypes[3]) { if (width > height) { cHeight = options.imageSize || height; cWidth = cHeight * width / height; } else { cWidth = options.imageSize || width; cHeight = cWidth * height / width; } } else { cWidth = width * options.scale; cHeight = height * options.scale; } var img = document.createElement('img'); img.src = url; // Draw image in canvas canvas.width = cWidth; canvas.height = cHeight; ctx.drawImage(img, 0, 0, cWidth, cHeight); var result = canvas.toDataURL(options.imageType, options.quality); return options.toBlob ? base64ToBlob(result) : result }) }) } export { canvasSupport, getNaturalSize, getSizeOfUrl, imgCompress };