uni-app图像(头像)选择,截取,压缩,上传的分享功能
uni-app图像(头像)选择,截取,压缩,上传的分享功能 思路:
- 通过拍照或者选择一张照片
- 将照片作为底,一个正方形容器作为边界。通过移动正方形容器获取所需图形的边界。
- 截取图片,并压缩到指定大小。
- 上传到服务器。
具体实现:
-
获取照片资源
-
1.1 从相册选择
function chooseImgFromAlbums() { plus.gallery.pick(function(file) { changeToLocalUrl(file); }, function(err) { console.log(JSON.stringify(err)); }, { filter: 'image', multiple: false }); }
-
1.2 拍照
function chooseImgFromPictures() { var cmr = plus.camera.getCamera(); cmr.captureImage(function(file) { changeToLocalUrl(file); }, function(err) { console.log(JSON.stringify(err)); }, { index: '2', }); }
-
1.3 相册选择和拍照选择返回的路径都是绝对路径,为了让其显示在img里面,我们需要转换为本地路径URL地址。此处打开一张新页面来对图片进行处理
function changeToLocalUrl(path) { plus.io.resolveLocalFileSystemURL(path, function(entry) { openWindow('uploadImg.html?src=' + entry.toLocalURL()); }); }
-
-
以一个正方形容器截取图片。
功能很简单:点击放大,缩小可以放大缩小正方形的区域。用手指移动正方形,来改变正方形所包含的内容。
实现的思路:通过监听正方形的touchstart和touchmove事件,改变它的top,left值。实现移动。
具体代码如下:
var Clip = { size: 12, range: {}, topCss: 0, leftCss: 0, touchX: 0, touchY: 0, timer: null, changeBase: function(index) { this.size += index; $('#clip').css({ height: this.size + 'rem', width: this.size + 'rem', lineHeight: this.size + 'rem' }); this.changeRange(); }, changeRange: function() { this.topCss = (($('body').height() - baseSize * extraHeight - baseSize * this.size) / 2 + baseSize * headerHeight); this.leftCss = (($('body').width() - baseSize * this.size) / 2); this.changeClipStyle(this.leftCss, this.topCss); var minTop = (($('body').height() - baseSize * extraHeight - $('#img').height()) / 2 + baseSize * headerHeight); var maxTop = $('body').height() - (($('body').height() - baseSize * extraHeight - $('#img').height()) / 2 - baseSize * footerHeght - baseSize * this.size); var minLeft = 0; var maxLeft = $('body').width() - baseSize * this.size; this.range = { minTop: minTop, maxTop: maxTop, minLeft: minLeft, maxLeft: maxLeft }; }, initEvent: function() { mui('body').on('tap', '#enlarge', function(e) { Clip.changeBase(1); }); mui('body').on('tap', '#reduce', function(e) { Clip.changeBase(-1); }) var clip = document.getElementById('clip'); clip.addEventListener('touchstart', function(event) { Clip.touchX = event.touches ? event.touches[0].clientX : event.screenX; Clip.touchY = event.touches ? event.touches[0].clientY : event.screenY; event.preventDefault(); }); clip.addEventListener('touchmove', function(event) { if(Clip.timer != null) { return; } Clip.timer = setTimeout(function() { var x = event.touches ? event.touches[0].clientX : event.screenX; var y = event.touches ? event.touches[0].clientY : event.screenY; var disX = x - Clip.touchX; var disY = y - Clip.touchY; var nowLeft = Clip.leftCss + disX; var nowTop = Clip.topCss + disY; if(nowLeft < Clip.range.minLeft) { nowLeft = Clip.range.minLeft; } if(nowLeft > Clip.range.maxLeft) { nowLeft = Clip.range.maxLeft; } if(nowTop < Clip.range.minTop) { nowTop = Clip.range.minTop; } if(nowTop > Clip.range.maxTop) { nowTop = Clip.range.maxTop; } Clip.changeClipStyle(nowLeft, nowTop); Clip.touchX = x; Clip.touchY = y; Clip.timer = null; }, 20); }); }, changeClipStyle: function(leftCss, topCss) { $('#clip').css({ left: leftCss + 'px', top: topCss + 'px' }); Clip.leftCss = leftCss; Clip.topCss = topCss; } }
-
移动到正方形到合适的区域后,点击完成,就将完成截取图片和压缩图片的功能。
主要思路是:调用plus.zip.compressImage函数来完成截取和压缩
3.1 首先,需要计算出宽高的百分比和离图片左上角的top和left的百分比。同样根据布局不同,计算方式不同。
//获取width和height的百分比 var widthPix = (Clip.size * baseSize / $('#img').width()).toFixed(2) * 100; var heightPix = (Clip.size * baseSize / $('#img').height()).toFixed(2) * 100; //获取左上角位置百分比 var topPix = ((Clip.topCss - Clip.range.minTop) / $('#img').height()).toFixed(2) * 100; var leftPix = (Clip.leftCss / $('#img').width()).toFixed(2) * 100;
3.2 截取
//对图片进行裁剪 plus.zip.compressImage( { src: search.src, dst: '_doc/a.jpg', overwrite: true, clip: { top: topPix + '%', left: leftPix + '%', width: widthPix + '%', height: heightPix + '%' } }, function(e) { resizeImage(e.target); //压缩图片 } );
3.3 截取图片之后,我们还需要进行压缩。
//再对图片进行压缩为270*270,再上传到服务器 function resizeImage(src) { plus.zip.compressImage( { src: src, dst: '_doc/a.jpg', overwrite: true, width: '270px', format: 'jpg', quality: 100 }, function(e) { plus.nativeUI.closeWaiting(); uploadImg(e.target); }, function(err) { plus.nativeUI.alert('未知错误!',function() { mui.back(); }); } ); }
-
上传图片到服务器。上传图片用的是plus.uploader,数据格式符合Multipart/form-data规范,也就是平时input type='file’那样一样
function uploadImg(src) { var task = plus.uploader.createUpload(ajaxUrl, { method: 'post', blocksize:204800, timeout: 10 }); task.addFile(src, {key: 'headImg'}); task.addData('type', 'uploadImg'); task.addData('userId', ); task.addEventListener('statechanged', stateChanged, false); task.start(); function stateChanged(upload, status) { if ( upload.state == 4 && status == 200 ) { plus.uploader.clear(); console.log(upload.responseText); } } }
在uni-app中实现图像(头像)的选择、截取、压缩和上传功能,可以通过以下步骤实现。以下是一个简单的代码示例,展示了如何集成这些功能。
1. 选择图像
使用uni.chooseImage API来选择图像:
uni.chooseImage({
count: 1, // 只选择一张图片
sizeType: ['original', 'compressed'], // 可以选择原图或压缩后的图片
sourceType: ['album', 'camera'], // 可以从相册选择或拍照
success: (res) => {
const tempFilePaths = res.tempFilePaths;
this.handleImage(tempFilePaths[0]);
}
});
2. 图像截取(可选)
如果需要截取图像,可以使用canvas进行裁剪。以下是一个简单的裁剪示例:
handleImage(filePath) {
uni.getImageInfo({
src: filePath,
success: (imageInfo) => {
const ctx = uni.createCanvasContext('myCanvas');
const width = 100; // 裁剪后的宽度
const height = 100; // 裁剪后的高度
const x = (imageInfo.width - width) / 2; // 裁剪起始点的x坐标
const y = (imageInfo.height - height) / 2; // 裁剪起始点的y坐标
ctx.drawImage(filePath, x, y, width, height, 0, 0, width, height);
ctx.draw(false, () => {
uni.canvasToTempFilePath({
canvasId: 'myCanvas',
destWidth: width,
destHeight: height,
success: (res) => {
this.compressAndUpload(res.tempFilePath);
}
});
});
}
});
}
3. 图像压缩
可以使用uni.compressImage API进行压缩,但前面已经通过canvas裁剪并调整了尺寸,这一步可以省略。如果仍需额外压缩,可以如下使用:
uni.compressImage({
src: tempFilePath,
quality: 80, // 压缩质量
success: (res) => {
this.uploadImage(res.tempFilePath);
}
});
注意:这里的tempFilePath
是裁剪后的图像路径。
4. 上传图像
使用uni.uploadFile API上传图像:
compressAndUpload(filePath) {
uni.uploadFile({
url: 'https://your-server-upload-url', // 上传地址
filePath: filePath,
name: 'file',
formData: {
user: 'test'
},
success: (uploadFileRes) => {
console.log('上传成功:', uploadFileRes.data);
},
fail: (err) => {
console.error('上传失败:', err);
}
});
}
总结
上述代码展示了如何在uni-app中选择、截取(通过canvas)、压缩(可选)和上传图像。注意,实际应用中需要根据具体需求调整代码,例如错误处理、用户交互等。此外,为了提升用户体验,可以在上传过程中显示加载动画或进度条。