<view>
<radio :value="item.value" :checked="index === current" />
</view>
<view>{{ item.name }}</view>
</label>
</radio-group>
<view class="content">
<movable-area
v-if="imageInfo.movableWidth"
class="map-area-wrap" style="{ width: imageInfo.movableWidth + 'px',
height: imageInfo.movableHeight + 'px',
}"
>
<movable-view
direction="all"
@change="movablechange"
@scale="movablescale"
scale style="{ width: imageInfo.dWidth + 'px',
height: imageInfo.dHeight + 'px',
}"
>
<image src="imageUrl" alt=""
mode="aspectFit"
class="img"
id="elementId"
v-if="imageUrl"
style="{
width: imageInfo.dWidth + 'px',
height: imageInfo.dHeight + 'px',
}"
/>
</movable-view>
</movable-area>
<view
class="line"
style="{
width: imageInfo.movableWidth + 'px',
height: imageInfo.movableHeight + 'px',
marginLeft: '-' + imageInfo.movableWidth / 2 + 'px',
}"
</view>
</view>
图片信息:
<view>原图宽度: {{ imageInfo.width }}</view>
<view>原图高度: {{ imageInfo.height }}</view>
<view>裁剪后宽度: {{ imageInfo.cWidth }}</view>
<view>裁剪后高度: {{ imageInfo.cHeight }}</view>
<view
style="{ width: imageInfo.canvasWidth + 'px',绘制页面宽度: {{ imageInfo.movableWidth }} 渲染图片宽度:
{{ imageInfo.dWidth }}</view<view
绘制页面高度: {{ imageInfo.movableHeight }} 渲染图片宽度:
{{ imageInfo.dHeight }}</view<view>绘制图片/画布宽度: {{ imageInfo.canvasWidth }}</view>
<view>绘制图片/画布高度: {{ imageInfo.canvasHeight }}</view>
<button @click="test">裁剪图片</button>
<canvas
class="canvas"
canvas-id="myCanvas"
height: imageInfo.canvasHeight + 'px',
}"
></canvas>
</view>
</template>
<script>
import { mapGetters } from "vuex";
export default {
computed: {
...mapGetters(["configList", "isLogin"]),
},
onLoad() {},
data() {
return {
items: [
{ value: "295x413", name: "295x413" },
{ value: "413x579", name: "413x579" },
{ value: "144x192", name: "144x192" },
{ value: "480x640", name: "480x640" },
{ value: "1050x1499", name: "1050x1499" },
{ value: "898x1205", name: "898x1205" },
],
imageUrl: "",
imageInfo: {},
current: 0,
corX: 0,
corY: 0,
scale: 1,
scleNum: 1,
};
},
methods: {
radioChange(value) {
this.imageInfo.cWidth = value.detail.value.split("x")[0];
this.imageInfo.cHeight = value.detail.value.split("x")[1];
this.imageInfo.movableWidth = Number(this.imageInfo.cWidth) / 2;
this.imageInfo.movableHeight = Number(this.imageInfo.cHeight) / 2;
this.imageInfo.canvasWidth = this.imageInfo.cWidth;
this.imageInfo.canvasHeight = this.imageInfo.cHeight;
console.log(value.detail.value);
console.log(this.imageInfo);
this.$forceUpdate();
},
selectImage() {
uni.chooseImage({
count: 1,
success: (res) => {
this.imageUrl = res.tempFilePaths[0];
this.$forceUpdate();
// 获取图片信息
uni.getImageInfo({
src: this.imageUrl,
success: (infoRes) => {
console.log(infoRes);
this.imageInfo = { ...this.imageInfo, ...infoRes }; // 将图片信息存储到data中
// 图片宽度适配裁剪框
this.scleNum =
this.imageInfo.width / 2 / this.imageInfo.movableWidth;
this.imageInfo.dWidth = this.imageInfo.movableWidth;
this.imageInfo.dHeight = this.imageInfo.height / 2 / this.scleNum;
if (this.imageInfo.dHeight < this.imageInfo.movableHeight) {
this.scleNum =
this.imageInfo.height / 2 / this.imageInfo.movableHeight;
this.imageInfo.dWidth = this.imageInfo.width / 2 / this.scleNum;
this.imageInfo.dHeight = this.imageInfo.movableHeight;
}
},
fail: (infoErr) => {
console.error(infoErr);
},
});
},
});
},
// 移动
movablechange(event) {
console.log("移动", event.detail);
this.corX = event.detail.x * 2; // 页面上缩小了2倍 回调
this.corY = event.detail.y * 2;
},
// 缩放
movablescale(event) {
this.scale = event.detail.scale;
this.corX = event.detail.x * 2; // 页面上缩小了2倍 回调
this.corY = event.detail.y * 2;
console.log("缩放", event.detail);
},
test() {
console.log(this.corX, this.corY, this.imageInfo.canvasWidth);
// 创建canvas绘图上下文
const context = uni.createCanvasContext("myCanvas", this);
context.drawImage(
this.imageUrl,
0, // 源图像的矩形选择框的左上角 X 坐标
0, // 源图像的矩形选择框的左上角 Y 坐标
this.imageInfo.canvasWidth, // 源图像的矩形选择框的宽度
this.imageInfo.canvasHeight, // 源图像的矩形选择框的高度
this.corX, // 图像的左上角在目标canvas上 X 轴的位置
this.corY, // 图像的左上角在目标canvas上 Y 轴的位置
(this.imageInfo.width * this.scale) / this.scleNum, // 在目标画布上绘制图像的宽度,允许对绘制的图像进行缩放
(this.imageInfo.height * this.scale) / this.scleNum // 在目标画布上绘制图像的高度,允许对绘制的图像进行缩放
); // 替换为实际图片路径
// 将canvas内容转换为临时文件路径
context.draw(false, () => {
uni.canvasToTempFilePath({
canvasId: "myCanvas",
// canvas,
// canvasId,
// x: 200,
// y: 200,
// width: this.imageInfo.canvasWidth,
// height: this.imageInfo.canvasHeight,
// destWidth: this.imageInfo.canvasWidth, // 必要,保证生成图片宽度不受设备分辨率影响
// destHeight: this.imageInfo.canvasHeight, // 必要,保证生成图片高度不受设备分辨率影响
// fileType: "png", // 目标文件的类型,默认png
success: (res) => {
const tempFilePath = res.tempFilePath;
console.log(tempFilePath);
// 使用 uni.compressImage() 方法对图片进行压缩
uni.compressImage({
src: tempFilePath,
// quality: 1, // 设置压缩质量,范围为 1-100
success: (compressRes) => {
const compressedFilePath = compressRes.tempFilePath;
// 保存图片到相册
uni.saveImageToPhotosAlbum({
filePath: compressedFilePath,
success: () => {
uni.showToast({
title: "保存成功",
icon: "success",
});
},
fail: (error) => {
uni.showToast({
title: "保存失败",
icon: "none",
});
console.error(error);
},
});
},
fail: (compressErr) => {
console.error(compressErr);
},
});
},
fail: (res) => {
console.error(res);
},
});
});
},
generateImage() {
uni
.createSelectorQuery()
.select("#elementId")
.boundingClientRect((rect) => {
console.log(rect);
// 创建canvas绘图上下文
const context = uni.createCanvasContext("myCanvas", this);
// context.drawImage('/static/images/index/icon-left.png', rect.left, rect.top, rect.width, rect.height, 0, 0, rect.width, rect.height); // 替换为实际图片路径
context.drawImage(
"/static/images/index/icon-left.png",
200,
200,
616,
768,
0,
0,
616,
768
); // 替换为实际图片路径
// context.drawImage("/static/images/index/icon-left.png"); // 替换为实际图片路径
// 将canvas内容转换为临时文件路径
context.draw(false, () => {
uni.canvasToTempFilePath({
canvasId: "myCanvas",
success: (res) => {
const tempFilePath = res.tempFilePath;
console.log(tempFilePath);
// 使用 uni.compressImage() 方法对图片进行压缩
uni.compressImage({
src: tempFilePath,
quality: 30, // 设置压缩质量,范围为 1-100
success: (compressRes) => {
const compressedFilePath = compressRes.tempFilePath;
// 保存图片到相册
uni.saveImageToPhotosAlbum({
filePath: compressedFilePath,
success: () => {
uni.showToast({
title: "保存成功",
icon: "success",
});
},
fail: (error) => {
uni.showToast({
title: "保存失败",
icon: "none",
});
console.error(error);
},
});
},
fail: (compressErr) => {
console.error(compressErr);
},
});
},
fail: (res) => {
console.error(res);
},
});
});
})
.exec();
},
},
};
</script>
<style lang="scss">
.img {
width: 300px;
}
.canvas {
width: 616px;
height: 768px;
}
.map-area-wrap {
margin: 0 auto;
background-color: #eee;
margin-bottom: 50px;
.max {
width: 100%;
height: 100%;
}
}
.content {
position: relative;
.line {
position: absolute;
left: 50%;
top: 0;
border: 1px solid #fff;
}
}
</style>
1***@qq.com (作者)
确实支付宝小程序的写法也存在这个问题
2023-08-14 09:33
DCloud_UNI_Anne
回复 1***@qq.com: 请反馈到支付宝小程序社区
2023-08-14 14:15