用vue3的写法结合uniapp在微信小程序中实现图片压缩、调整分辨率、做缩略图功能

在UniApp中使用Vue3实现微信小程序图片处理功能

下面是一个完整的UniApp组件实现,专门针对微信小程序环境,包含图片压缩、分辨率调整和缩略图生成功能。

完整组件代码

xml 复制代码
<template> 
<view class="image-processor">
<view class="header"> 
<text class="title">微信小程序图片处理工具</text>
</view>
<view class="upload-area" @click="chooseImage">
<text>点击选择图片</text> 
</view> 
<view v-if="originalImage" class="controls">
<view class="control-group">
<text>压缩质量 (0-100):</text> 
<slider :value="quality" min="0" max="100" @change="onQualityChange" show-value /> 
</view>
<view class="control-group">
<text>最大宽度:</text> 
<input type="number" v-model="maxWidth" min="100" />
</view> 
<view class="control-group">
<text>最大高度:</text> 
<input type="number" v-model="maxHeight" min="100" /> 
</view>
<view class="control-group">
<text>缩略图尺寸:</text> 
<input type="number" v-model="thumbnailSize" min="50" /> 
</view> 
<button @click="processImage" type="primary">处理图片</button> 
</view> 
<view v-if="processedImage" class="results">
<view class="image-container">
<text class="subtitle">原始图片 ({{ originalSize }})</text> 
<image :src="originalImage" mode="widthFix" class="original" />
</view>
<view class="image-container"> 
<text class="subtitle">处理后图片 ({{ processedSize }})</text>
<image :src="processedImage" mode="widthFix" class="processed" />
</view>
<view class="image-container" v-if="thumbnailImage">
<text class="subtitle">缩略图 ({{ thumbnailSize }}px)</text> 
<image :src="thumbnailImage" mode="widthFix" class="thumbnail" /> 
</view>
<button @click="saveImage" type="primary" class="download-btn">保存到相册</button> 
</view>
<canvas canvas-id="thumbnailCanvas" style="position: absolute; left: -9999px; width: 300px; height: 300px;"></canvas>
</view> 
</template>

js

ini 复制代码
import { ref } from 'vue';
const originalImage = ref(null); 
const processedImage = ref(null); 
const thumbnailImage = ref(null); 
const quality = ref(80);
const maxWidth = ref(800);
const maxHeight = ref(600); 
const thumbnailSize = ref(200);
const originalSize = ref('');
const processedSize = ref('');
const tempFilePath = ref('');
const chooseImage = async () => { 
try {
const res = await uni.chooseImage({
count: 1,
sourceType: ['album', 'camera'],
sizeType: ['original', 'compressed'] });
if (res.tempFilePaths.length > 0) { 
tempFilePath.value = res.tempFilePaths[0];
originalImage.value = tempFilePath.value; // 获取文件信息
const fileInfo = await uni.getFileInfo({
filePath: tempFilePath.value
});
originalSize.value = formatFileSize(fileInfo.size);
} } catch (error) { 
uni.showToast({ 
title: '选择图片失败', icon: 'none'
}); 
console.error(error);
} };
const onQualityChange = (e) => { 
quality.value = e.detail.value;
}; 
const processImage = async () => { 
if (!originalImage.value) return;
uni.showLoading({title: '处理中...' });
try { // 压缩并调整尺寸
const compressedRes = await uni.compressImage({
src: tempFilePath.value,
quality: quality.value, 
width: maxWidth.value, 
height: maxHeight.value
});
processedImage.value = compressedRes.tempFilePath; 
// 获取处理后文件大小 
const fileInfo = await uni.getFileInfo({ filePath: compressedRes.tempFilePath
});
processedSize.value = formatFileSize(fileInfo.size);
// 生成缩略图 
await generateThumbnail(compressedRes.tempFilePath);uni.hideLoading(); 
} catch (error) { 
uni.hideLoading();
uni.showToast({ 
title: '图片处理失败', icon: 'none'
}); console.error(error); } };
const generateThumbnail = async (filePath) => { 
try { 
// 使用canvas生成缩略图
const ctx = uni.createCanvasContext('thumbnailCanvas', this);
// 获取图片信息
const imgInfo = await new Promise((resolve, reject) => { 
uni.getImageInfo({
src: filePath, success: resolve, fail: reject });
}); 
// 计算缩略图尺寸,保持宽高比 
let width = thumbnailSize.value; 
let height = (imgInfo.height / imgInfo.width) * width; 
// 绘制缩略图
ctx.drawImage(filePath, 0, 0, width, height);
// 将canvas转为临时文件 
const tempFile = await new Promise((resolve, reject) => { 
ctx.draw(false, () => { 
uni.canvasToTempFilePath({ 
canvasId: 'thumbnailCanvas', quality: 0.7, success: resolve, fail: reject
}, this); }); }); 
thumbnailImage.value = tempFile.tempFilePath; 
} catch (error) { 
console.error('生成缩略图失败:', error);
} };
const saveImage = async () => { 
if (!processedImage.value) return;
try { await uni.saveImageToPhotosAlbum({ filePath: processedImage.value
});
uni.showToast({ title: '保存成功', icon: 'success' }); }
catch (error) { uni.showToast({ title: '保存失败', icon: 'none' });
console.error(error); } };
const formatFileSize = (bytes) => { 
if (bytes === 0) return '0 Bytes';
const k = 1024; 
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; }; ;

css

xml 复制代码
<style lang="scss">
.image-processor {
padding: 20rpx;
font-family: -apple-system, BlinkMacSystemFont, 
'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 
'Open Sans', 'Helvetica Neue', sans-serif;
} 
.header { 
margin-bottom: 30rpx; 
text-align: center; 
} 
.title { 
font-size: 36rpx; 
font-weight: bold;
} 
.upload-area {
margin: 30rpx 0;
padding: 40rpx;
border: 2rpx dashed #ccc;
border-radius: 10rpx;
text-align: center;
color: #666;
} 
.controls {
margin: 30rpx 0;
padding: 20rpx;
background: #f5f5f5; 
border-radius: 10rpx;
} 
.control-group {
margin-bottom: 20rpx;
text{
display: block;
margin-bottom: 10rpx;
font-size: 28rpx;
}
input {
border: 1rpx solid #ddd; 
padding: 10rpx;
border-radius: 5rpx;
width: 100%;
} } 
.results {
margin-top: 30rpx;
} 
.image-container {
margin-bottom: 30rpx;
border: 1rpx solid #eee;
padding: 20rpx;
border-radius: 10rpx;
} 
.subtitle {
display: block; 
margin-bottom: 15rpx; 
font-size: 28rpx;
font-weight: bold; 
} 
.original {
border: 4rpx solid #1890ff;
}
.processed {
border: 4rpx solid #52c41a;
}
.thumbnail {
border: 4rpx solid #faad14;
}
.download-btn { 
margin-top: 30rpx;
}
</style>
  1. API差异处理

    • 使用uni.chooseImage代替浏览器文件选择
    • 使用uni.compressImage进行图片压缩
    • 使用uni.canvasToTempFilePath将canvas转为图片
  2. 性能优化

    • 使用微信小程序的原生压缩API,性能更好
    • 隐藏的canvas用于生成缩略图,不影响界面
  3. 权限处理

    • 需要在小程序配置中声明相册权限
    • 处理用户拒绝授权的情况
相关推荐
斯~内克几秒前
基于Vue.js和PDF-Lib的条形码生成与批量打印方案
前端·vue.js·pdf
阴阳怪气乌托邦1 分钟前
别再啃OA代码了!低代码"搭积木"式搞数智化,我直接少写500行
前端·低代码
beelan5 分钟前
v-on的思考
前端
山河木马8 分钟前
前端学习C++之:.h(.hpp)与.cpp文件
前端·javascript·c++
用户9272472502198 分钟前
PHP + CSS + JS + JSON 数据采集与展示系统,支持伪静态
前端
努力只为躺平13 分钟前
一文搞懂 Promise 并发控制:批量执行 vs 最大并发数,实用场景全解析!
前端·javascript
李大玄15 分钟前
Google浏览器拓展工具 "GU"->google Utils
前端·javascript·github
爱编程的喵15 分钟前
从DOM0到事件委托:揭秘JavaScript事件机制的性能密码
前端·javascript·dom
蓝倾21 分钟前
京东批量获取商品SKU操作指南
前端·后端·api
JSLove27 分钟前
常见 npm 报错问题
前端·npm