赞
踩
此篇文章只供自己参考 我只是代码的搬运工
转载自uniapp插件市场
转载自uniapp插件市场
<template> <view class="image-compress-container"> <!-- #ifndef H5 --> <canvas :style="{width: W + 'px', height: H + 'px', visibility: 'hidden'}" class="canvas" canvas-id="canvas"></canvas> <!-- #endif --> </view> </template> <script> export default { data () { return { W: '', H: '', canvas: null, ctx: null, maxW: 1024, maxH: 1024, quality: 0.8, base64: false, showLoading: '正在压缩', mask: true } }, methods: { async compress (args, options = {}) { return new Promise(async (resolve, reject) => { let files; if (arguments[0].tempFiles || arguments[0].tempFilePaths) { files = arguments[0].tempFilePaths || arguments[0].tempFiles; }; if (arguments[0].files) { files = arguments[0].files; } if (!files instanceof Array) { reject('数据格式错误'); } if (!files.length) { reject('数据不能为空'); } this.maxW = options.maxW || 1024; this.maxH = options.maxH || 1024; this.quality = options.quality || 0.8; this.base64 = options.base64 || false; this.showLoading = options.showLoading === true ? '正在压缩' : typeof options.showLoading === 'string' ? options.showLoading : false; this.mask = options.mask || true; if (this.showLoading) { uni.showLoading({ title: this.showLoading, mask: this.mask }) } try { const result = await this.convertImageToBase64(files); resolve(result); uni.hideLoading(); } catch (error) { reject(error); uni.hideLoading(); } }) }, toBase64H5 (file) { return new Promise((resolve, reject) => { let result = []; for (let i = 0; i < file.length; i++) { let reader = new FileReader(); let base64Result; reader.addEventListener('load', (e) => { base64Result = reader.result || e.target.result; let filename = file[i].name.slice(0, file[i].name.lastIndexOf('.')); result.push({base64: base64Result, filename}); reader = null; if (result.length === file.length) { resolve(result); } }); reader.readAsDataURL(file[i]); } }) }, compressResultH5 (base64Item) { return new Promise((resolve, reject) => { let maxW = this.maxW; let maxH = this.maxH; let ratio, needCompress = false; let image = new Image(); image.src = base64Item.base64; image.addEventListener('load', () => { if (image.naturalWidth > maxW) { needCompress = true; ratio = image.naturalWidth / maxW; maxH = image.naturalHeight / ratio; } if (image.naturalHeight > maxH) { needCompress = true; ratio = image.naturalHeight / maxH; maxW = image.naturalWidth / ratio; } if (!needCompress) { maxW = image.naturalWidth; maxH = image.naturalWidth; } if (!this.canvas) { this.canvas = document.createElement('canvas'); } this.canvas.width = maxW; this.canvas.height = maxH; const ctx = this.canvas.getContext('2d'); ctx.clearRect(0, 0, maxW, maxH); ctx.drawImage(image, 0, 0, maxW, maxH); const compressImg = this.canvas.toDataURL('image/jpeg', this.quality); let file = this._dataURLtoFile(compressImg, base64Item.filename); if (this.base64) { resolve({base64: compressImg, file}); } else { resolve({file}); } image = null; // ratio: base64Item.base64.length / compressImg.length }) }) }, compressImageH5 (base64Result) { let result = []; return new Promise(async (resolve, reject) => { for (let i = 0; i < base64Result.length; i++) { let res = await this.compressResultH5(base64Result[i]); result.push(res); if (result.length === base64Result.length) { resolve(result); this.canvas = null; } } }) }, async convertImageToBase64 (files) { // #ifdef H5 if (typeof files[0] === 'object') { let result = await this.toBase64H5(files); return await this.compressImageH5(result); } if (typeof files[0] === 'string') { let result = files.map(item => { return { base64: item } }); return await this.compressImageH5(result); } return []; // #endif // #ifndef H5 if (typeof files[0] === 'string') { const result = await this.getImgInfoWX(files); return await this.compressImageWX(result); } if (typeof files[0] === 'object') { files = files.map(item => { return item.path }); const result = await this.getImgInfoWX(files); return await this.compressImageWX(result); } return []; // #endif return []; }, getImgInfoWX (tempFilePaths) { let result = []; return new Promise((resolve, reject) => { for (let i = 0; i < tempFilePaths.length; i++) { uni.getImageInfo({ src: tempFilePaths[i], success: (image) => { result.push({tempFilePaths: tempFilePaths[i], image}); if (result.length === tempFilePaths.length) { resolve(result); } } }); } }) }, compressResultWX (tempFilePaths) { return new Promise((resolve, reject) => { let maxW = this.maxW; let maxH = this.maxH; let ratio, needCompress = false; tempFilePaths.image.width = Number(tempFilePaths.image.width); tempFilePaths.image.height = Number(tempFilePaths.image.height); if (tempFilePaths.image.width > maxW) { needCompress = true; ratio = tempFilePaths.image.width / maxW; maxH = tempFilePaths.image.height / ratio; } if (tempFilePaths.image.height > maxH) { needCompress = true; ratio = tempFilePaths.image.height / maxH; maxW = tempFilePaths.image.width / ratio; } if (!needCompress) { maxW = tempFilePaths.image.width; maxH = tempFilePaths.image.height; } this.W = maxW; this.H = maxH; if (!this.ctx) { this.ctx = uni.createCanvasContext('canvas', this); } this.ctx.clearRect(0, 0, this.W, this.H); this.ctx.drawImage(tempFilePaths.tempFilePaths, 0, 0, maxW, maxH); setTimeout(()=>{ this.ctx.draw(false, () => { uni.canvasToTempFilePath({ x: 0, y: 0, width: this.W, height: this.H, destWidth: this.W, destHeight: this.H, canvasId: 'canvas', quality: this.quality, success: (res) => { let file = res.tempFilePath; let base64 = uni.getFileSystemManager().readFileSync(file, 'base64'); base64 = `data:image/jpeg;base64,${base64}` if (this.base64) { resolve({file, base64}); } else { resolve({file}); } } }, this) }); },1500) }) }, compressImageWX (tempFilePaths) { let result = []; return new Promise(async (resolve, reject) => { for (let i = 0; i < tempFilePaths.length; i++) { let res = await this.compressResultWX(tempFilePaths[i]); result.push(res); if (result.length === tempFilePaths.length) { resolve(result); this.ctx = null; } } }) }, _dataURLtoFile (dataurl, filename) { let arr = dataurl.split(','); let 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 File([u8arr], filename, {type:mime}); } } } </script> <style scoped> .image-compress-container { width: 0; height: 0; margin: 0; padding: 0; overflow: hidden; position: absolute; z-index: -100000; } </style>
function getLocalFilePath(path) { if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path.indexOf('_downloads') === 0) { return path } if (path.indexOf('file://') === 0) { return path } if (path.indexOf('/storage/emulated/0/') === 0) { return path } if (path.indexOf('/') === 0) { var localFilePath = plus.io.convertAbsoluteFileSystem(path) if (localFilePath !== path) { return localFilePath } else { path = path.substr(1) } } return '_www/' + path } function dataUrlToBase64(str) { var array = str.split(',') return array[array.length - 1] } var index = 0 function getNewFileId() { return Date.now() + String(index++) } function biggerThan(v1, v2) { var v1Array = v1.split('.') var v2Array = v2.split('.') var update = false for (var index = 0; index < v2Array.length; index++) { var diff = v1Array[index] - v2Array[index] if (diff !== 0) { update = diff > 0 break } } return update } export function pathToBase64(path) { return new Promise(function(resolve, reject) { if (typeof window === 'object' && 'document' in window) { if (typeof FileReader === 'function') { var xhr = new XMLHttpRequest() xhr.open('GET', path, true) xhr.responseType = 'blob' xhr.onload = function() { if (this.status === 200) { let fileReader = new FileReader() fileReader.onload = function(e) { resolve(e.target.result) } fileReader.onerror = reject fileReader.readAsDataURL(this.response) } } xhr.onerror = reject xhr.send() return } var canvas = document.createElement('canvas') var c2x = canvas.getContext('2d') var img = new Image img.onload = function() { canvas.width = img.width canvas.height = img.height c2x.drawImage(img, 0, 0) resolve(canvas.toDataURL()) canvas.height = canvas.width = 0 } img.onerror = reject img.src = path return } if (typeof plus === 'object') { plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), function(entry) { entry.file(function(file) { var fileReader = new plus.io.FileReader() fileReader.onload = function(data) { resolve(data.target.result) } fileReader.onerror = function(error) { reject(error) } fileReader.readAsDataURL(file) }, function(error) { reject(error) }) }, function(error) { reject(error) }) return } if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) { wx.getFileSystemManager().readFile({ filePath: path, encoding: 'base64', success: function(res) { resolve('data:image/png;base64,' + res.data) }, fail: function(error) { reject(error) } }) return } reject(new Error('not support')) }) } export function base64ToPath(base64) { return new Promise(function(resolve, reject) { if (typeof window === 'object' && 'document' in window) { base64 = base64.split(',') var type = base64[0].match(/:(.*?);/)[1] var str = atob(base64[1]) var n = str.length var array = new Uint8Array(n) while (n--) { array[n] = str.charCodeAt(n) } return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], { type: type }))) } var extName = base64.split(',')[0].match(/data\:\S+\/(\S+);/) if (extName) { extName = extName[1] } else { reject(new Error('base64 error')) } var fileName = getNewFileId() + '.' + extName if (typeof plus === 'object') { var basePath = '_doc' var dirPath = 'uniapp_temp' var filePath = basePath + '/' + dirPath + '/' + fileName if (!biggerThan(plus.os.name === 'Android' ? '1.9.9.80627' : '1.9.9.80472', plus.runtime.innerVersion)) { plus.io.resolveLocalFileSystemURL(basePath, function(entry) { entry.getDirectory(dirPath, { create: true, exclusive: false, }, function(entry) { entry.getFile(fileName, { create: true, exclusive: false, }, function(entry) { entry.createWriter(function(writer) { writer.onwrite = function() { resolve(filePath) } writer.onerror = reject writer.seek(0) writer.writeAsBinary(dataUrlToBase64(base64)) }, reject) }, reject) }, reject) }, reject) return } var bitmap = new plus.nativeObj.Bitmap(fileName) bitmap.loadBase64Data(base64, function() { bitmap.save(filePath, {}, function() { bitmap.clear() resolve(filePath) }, function(error) { bitmap.clear() reject(error) }) }, function(error) { bitmap.clear() reject(error) }) return } if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) { var filePath = wx.env.USER_DATA_PATH + '/' + fileName wx.getFileSystemManager().writeFile({ filePath: filePath, data: dataUrlToBase64(base64), encoding: 'base64', success: function() { resolve(filePath) }, fail: function(error) { reject(error) } }) return } reject(new Error('not support')) }) }
<template> <view> <view @click="shoot">上传</view> <x-compress ref="xCompress"></x-compress> // 放到template里就可以 随便放一个地方 </view> </template> <script> import xCompress from '压缩图片组件路径.vue'; import { pathToBase64, base64ToPath } from 'base64文件转为临时文件路径.js' //npm下载方式 //npm i image-tools --save //import { pathToBase64, base64ToPath } from 'image-tools' export default { data() { return { } }, methods: { // 点击上传 shoot() { uni.chooseImage({ sourceType: ['camera','album'], count : 1, success: async (res) => { // console.log('压缩前图片体积', res.tempFiles[0].size); try { // 调用组件的compress方法开始压缩 let result = await this.$refs.xCompress.compress(res, { base64: true, // 是否也返回base64格式,默认false,既不返回base64格式图片数据,反之亦然 maxW: 1024 , // 当图片宽度超过1024大小时最大为1024(高度也会按比例缩放),默认也是1024 maxH: 1024, // 当图片高度超过1024大小时最大为1024(宽度也会按比例缩放),默认也是1024 quality: 0.8, // 压缩质量(0-1),默认为0.8,值越小压缩质量越大 showLoading: true, // 是否显示loading提示,也可以传入一个字符串(相当于loading时的title),默认为true, mask: true // 当showLoading为true时,是否显示遮罩层,默认为true }); // console.log('result', result); // 调用组件的base64ToPath方法转为临时路径 base64ToPath(result[0].base64) .then(path => { console.log(path) // 最终图片 }) .catch(error => { console.error(error) }) } catch (error) { console.log('error', error); } } }) }, } } </script>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。