Uniapp使用上传组件,回显时图片显示感叹号,含解决思路


前言

  小程序项目中在实现上传图片时经常采用第三方组件UI,那么使用已经封装好的上传图片组件时页或多或少遇到一些无法处理的情况。

  举例:在使用u-upload上传组件时,回显的图片显示感叹号,打印错误结果为404错误,那么这种情况一般出现在上传的图片格式不规范,如:传入的格式不正确,但是在传入过高分辨率的图片时也会导致图片无法显示。

  解决思路:在经过反复测试发现,上传文件大小在20M内都可以正常上传、正常回显,但是一旦图片分辨率超过3000x3000时,图片可以正常上传,但回显为感叹号,打印错误输出为404,因此回显成功与否与上传时分辨率大小有密切关联,在上传文件时采用压缩分辨率即可解决此问题。


提示:以下是本篇文章正文内容,下面案例可供参考

一、问题复现

1.上传测试文件

1.上传<=2M图片文件,分辨率为1000x500;
2.上传>=10M图片文件,分辨率为2500x1500;
3.上传<=5M图片文件,分辨率为9000x5500;
  回显速度与网速有关,但1和2可以正常显示,第3张图片虽然只有4.5M但显示为感叹号

在这里插入图片描述

2.错误信息

  在u-upload组件中,通过@error事件可以打印出错误信息,获取此图片的网络接口为200,但打印出错误信息如下:

在这里插入图片描述

二、图片压缩

1.创建Canvas标签

  由于上传组件我这里是写在子组件中的,所以直接将Canvas标签放在了父页面,当然也可以放在子组件或者无父子关系,但是获取this的时候需要注意定向问题,这里就展示Canvas放在父页面的情况:

代码如下(示例):

<!--调整图片尺寸-->
<canvas style="width:100vw;height:100vw;position:fixed;left:100%;" id="picCanvas" type="2d"></canvas>

2.在u-upload的上传回调中引用压缩方法

代码如下(示例):

afterRead(event) {
	//获取上传的文件列表Ps:一次上传多张
	let lists = [].concat(event.file);
	for (let i = 0; i < lists.length; i++) {
	const item = lists[i];
	this.formData.files.push({
		...item,
		status: 'uploading',
		message: '上传中'
	});
	//引用压缩函数Ps:将文件的Url作为参数传入
	this.turnDownPic(item.thumb);
	//后面利用Uni的uploadFile上传即可
	uni.uploadFile({
		url: xxxxxx,
		//filePath传入压缩后的图片Url,这里的tempSrc声明在data()中
		filePath: this.tempSrc,
		name: xxxxxx,
		header: {
			xxxxxx
		},
		success: (res) => {
			xxxxxx
		},
		fail(err) {
			xxxxxx
		}
	}
}

3.在methods中定义压缩函数

代码如下(示例):

turnDownPic(picSrc) {
	//在Uni方法中无法获取到this需要提前指定
	var that = this;
	//返回Promise否则在压缩未完成时就已经上传了
	return new Promise(function(resolve, reject) {
		//获取原图片信息
		uni.getImageInfo({
			src: picSrc,
			success: function(res) {
				let canvasRatio = 1.2;//定义初始压缩比例,为了提升效率
				let picWidth = res.width;//图片原始宽
				let picHeight = res.height;//图片原始长
				//需要压缩则根据压缩比例进行压缩
				while (picWidth > 2500 || picHeight > 1500) {
					picWidth = Math.trunc(res.width / canvasRatio)
					picHeight = Math.trunc(res.height / canvasRatio)
					//如果需要更高效可将0.1提高为0.2
					canvasRatio = canvasRatio + 0.1;
				}
				//若当前分辨率无需压缩则直接返回原Url
				if (res.width === picWidth && res.height === picHeight) {
					that.tempSrc = thumb;
					resolve();
				} else {
					//以下代码在Canvas标签中生成需要的图片					
					uni.createSelectorQuery().select('#picCanvas').fields({
						node: true,
						size: true
					}).exec((res) => {
						try {
							const canvas = res[0].node
							const ctx = canvas.getContext('2d')
							let dpr = uni.getSystemInfoSync().pixelRatio
							canvas.width = picWidth
							canvas.height = picHeight
							const img = canvas.createImage()
							img.src = thumb
							img.onload = () => {
								ctx.drawImage(img, 0, 0, picWidth, picHeight); 
								//延迟200ms,防止最终的图片未绘制完毕
								setTimeout(() => {
									uni.canvasToTempFilePath({
										fileType: "jpg",
										canvas: canvas,
										destWidth: picWidth,
										destHeight: picHeight,
										success: function(res) {
											that.tempSrc = res.tempFilePath;
											resolve()
										}
									})
								}, 200)
							}
						} catch (e) {
							//异常后的操作
							reject(e);
						}
					})
				}
			}
		})
	});
},


总结

  关于图片压缩其实有很多例子都是通过Canvas重新绘制实现的,实现代码都大体相似,最主要是可以降低分辨率,而官方的压缩方法仅针对大小进行压缩,且不太好用,那么利用Canvas就可以实现分辨率的压缩,以上就是关于Uniapp项目使用上传组件时,上传的文件显示感叹号的解决思路,希望我的分享对您有帮助。

要实现uniapp拍照转文字回显的功能,可以借助uni-app插件uni-ocr,该插件提供了图片识别和文字识别的功能。 以下是实现步骤: 1. 安装uni-ocr插件,可以通过npm install uni-ocr命令进行安装。 2. 在页面中添加拍照按钮和图片显示区域,如下所示: ``` <view> <button type="primary" @click="takePhoto">拍照</button> <image v-if="imageUrl" :src="imageUrl"></image> <text v-if="ocrText">{{ ocrText }}</text> </view> ``` 3. 在页面的<script>标签中定义变量和方法,如下所示: ``` <script> import uniOcr from '@/uni_modules/uni-ocr/js_sdk/uni-ocr.js'; export default { data() { return { imageUrl: '', ocrText: '' } }, methods: { takePhoto() { uni.chooseImage({ count: 1, sizeType: ['original', 'compressed'], sourceType: ['camera'], success: (res) => { this.imageUrl = res.tempFilePaths[0]; this.recognizeText(); } }); }, recognizeText() { uniOcr.recognizeText({ path: this.imageUrl, success: (res) => { console.log(res); this.ocrText = res.text; }, fail: (err) => { console.log(err); } }); } } } </script> ``` 4. 在takePhoto方法中,调用uni.chooseImage方法选择拍摄照片,将照片路径存储在imageUrl变量中,并调用recognizeText方法进行文字识别。 5. 在recognizeText方法中,调用uni-ocr插件的recognizeText方法进行文字识别,识别成功后将识别的文本存储在ocrText变量中,并在页面中显示。 注意:为了使用uni-ocr插件,需要在manifest.json文件中配置权限,具体配置方法可以参考uni-ocr官方文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值