uniapp/微信小程序 上传图片 压缩(canvas)

最近遇到了个需要上传图片的需求,后端的接口对前端的图片大小有限制,但是具体限制多少咱也不知道,我看前辈代码是前端压缩图片然后再上传给后端,是基于canvas实现的,自己根据项目又稍微改动了一点点。话不多说上代码:

首先封装个canvas组件,我就直接贴代码了

<template>
	<view>
		<canvas class="canvas" canvas-id="canvas" :style="{
		    width: canvasStyle.width + 'px',
		    height: canvasStyle.height + 'px',
		  }"></canvas>
	</view>
</template>

<script>
	export default {
		data() {
			return {
                //此处的是canvas 的尺寸 也可以通过props传递
				canvasStyle: {
					width: 500,
					height: 500,
				},
			}
		},
		methods: {
			compressImg(_this, src) {
				let that = this
				// 等比例压缩图片 可指定图片宽高
				let w = that.canvasStyle.width;
				let h = that.canvasStyle.height;
				return new Promise((resolve, reject) => {
					uni.getImageInfo({
						src,
						success(res) {
							let originWidth = res.width;
							let originHeight = res.height;
							let maxWidth = w;
							let maxHeight = h;
							let targetWidth = originWidth;
							let targetHeight = originHeight;
							if (originWidth > maxWidth || originHeight > maxHeight) {
								if (originWidth / originHeight > maxWidth / maxHeight) {
									targetWidth = maxWidth;
									targetHeight = Math.round(
										maxWidth * (originHeight / originWidth)
									);
								} else {
									targetHeight = maxHeight;
									targetWidth = Math.round(
										maxHeight * (originWidth / originHeight)
									);
								}
							}
                            //canvas开始绘制图片
							let ctx = uni.createCanvasContext("canvas", _this)
							ctx.clearRect(0, 0, targetWidth, targetHeight)
							ctx.drawImage(src, 0, 0, maxWidth, maxHeight);
							ctx.draw(
								false,
								setTimeout(() => {
									uni.canvasToTempFilePath({
										canvasId: "canvas",
										destWidth: targetWidth,
										destHeight: targetHeight,
										fileType: "png",
										quality: 0.4,
										success: function(res1) {
											resolve(res1);
										},
										fail: function(res) {
											console.log(res.errMsg);
										},
									}, _this);
								}, 1000)
							);
						},
						fail(err) {
							console.log(err.errMsg);
						},
					});
				});
			},
			chooseImg() {

				let that = this

				uni.chooseImage({
					count: 1,
					sourceType: ['album', 'camera'],
					sizeType: ['original', 'compressed'],
					success: async (res) => {
						uni.showLoading({
							title: '正在上传...'
						})
						const result = await that.compressImg(this, res.tempFilePaths[0])
						uni.showToast({
							title: '上传成功',
							icon: 'none'
						})
                        //自定义事件,将绘制结果发出去
						that.$emit('upload', result)
					}
				})
			}
		}
	}
</script>

<style>
	.canvas {
		position: fixed;
		left: -1000vm;
		top: -1000vh;
	}
</style>

在界面中去使用

	import {addImgUrl } from '@/api/login.js'//引入api接口
	import {
		canvasPage
	} from '@/components/canvas.vue' //uniapp引入组件====微信小程序引入方式在界面json中
        
	//一定要注册,我老是忘记注册,或者直接在main.js中全局注册也许,省得每次都要引入注册
		components: {
			canvasPage,
		},

    //html结构中放
    <canvas-page ref="canvasPage" @upload="upload"></canvas-page>

    //methods方法
    
        //事件触发上传
    	select_image() {
				let that = this
                //通过$ref调用组件中的方法去选取照片
				that.$refs.canvasPage.chooseImg()
			},
            //组件的自定义事件,接收组件方法中绘制好的result
			upload(val) {
				let that = this
                //addImgUrl是上传图片的接口名
				addImgUrl({
					path: val.tempFilePath,//文件路劲
					fileName: '文件名'
				}).then((res) => {
					uni.hideLoading()
					if (res.statusCode == 200) {
                      //  赋值给变量展示上传好的图片
						that.imageUrl = (JSON.parse(res.data)).data.logoUrl
					}
				}).catch((err) => {
					uni.hideLoading()
				})
			},

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!如果您想要将 Uniapp 微信小程序中的界面转换为图片,可以尝试使用以下方法: 1. 使用 `uni.canvasToTempFilePath()` 方法将界面转换为图片 Uniapp 中提供了 `uni.canvasToTempFilePath()` 方法,可以将指定的 canvas 区域内容转换为临时文件路径。因此,我们可以通过将整个页面的内容绘制到一个 canvas 中,再将 canvas 转换为图片,来实现将界面转换为图片的功能。 下面是一个简单的示例代码: ```javascript // 获取 canvas 上下文 const query = uni.createSelectorQuery() query.select('#myCanvas').fields({ node: true, size: true }) .exec((res) => { const canvas = res[0].node const ctx = canvas.getContext('2d') // 绘制整个页面内容到 canvas 上 const page = getCurrentPages()[getCurrentPages().length - 1] const width = page.windowWidth const height = page.windowHeight const dpr = uni.getSystemInfoSync().pixelRatio canvas.width = width * dpr canvas.height = height * dpr ctx.scale(dpr, dpr) uni.renderPage(page).then(() => { uni.drawCanvas({ canvasId: 'myCanvas', x: 0, y: 0, width: width, height: height, destWidth: width * dpr, destHeight: height * dpr, }) }) // 将 canvas 转换为临时文件路径 uni.canvasToTempFilePath({ canvasId: 'myCanvas', success: (res) => { console.log(res.tempFilePath) // 可以将临时文件路径保存到本地或者上传到服务器 }, }) }) ``` 在上面的代码中,我们首先获取了当前页面的 canvas 上下文,并将整个页面的内容绘制到了 canvas 上。然后,我们使用 `uni.canvasToTempFilePath()` 方法将 canvas 转换为临时文件路径,最后可以将临时文件路径保存到本地或者上传到服务器。 2. 注意事项 需要注意的是,如果您的界面中包含了涉及用户隐私的内容(例如输入框、密码框等),则不应将整个界面转换为图片。另外,由于微信小程序的安全限制,界面转换为图片的功能在某些场景下可能会受到限制,具体情况需要根据实际测试结果而定。 希望以上内容能够帮助到您,如果您还有其他问题或者需要更详细的解答,请随时提出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值