uniappH5图片压缩上传

uniappH5图片压缩上传

此篇文章只供自己参考 我只是代码的搬运工

1.uniapp插件市场中的压缩插件

转载自uniapp插件市场

2.将压缩完返回的base64文件转为临时文件的js文件(可根据项目要求是否需要,不需要的话可跳过此步骤)

转载自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>


base64文件转为临时文件的js文件(也可以使用npm下载跳过这一步)
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>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值