封面
最近做项目的时候,需要做一个截图功能。用了一个别人写的截图工具,发现截出的图质量下降了,但是我们图片要用来做识别, 需要保证截出的图质量不下降。而且也不支持通过拖动来调整截图框的大小。所以这个截图工具无法满足需求。因为所以,就自己动手写了一个截图组件。
下面介绍一下实现原理和使用方法。
实现原理
组件wxml的层次结构图如下:
hierarchy.png
-
original canvas 用来绘制原图大小的图片,这样能保证截图后的质量不会下降,这个canvas是隐藏的。
-
movable-area是movable-view的容器,是官方提供的拖拽移动组件,用来移动截取框的四个角。这个组件支持多个点同时移动。
-
scale canvas用来绘制适应屏幕比例大小的图片(aspectFit),因为通常原图大小是超过屏幕长宽的。
-
move canvas是根据四个movable-view的位置绘制出截图框。
最后截图,通过四个点的位置计算出截图框的位置,然后放大对应原图大小的位置,得到在原图中的(x, y, width, height),最后通过官方提供的canvas接口截图。
-
wx.canvasToTempFilePath({
-
x: x,
-
y: y,
-
width: w,
-
height: h,
-
destWidth: w,
-
destHeight: h,
-
canvasId: 'originalCanvas',
-
success: function (res) {
-
}
-
)}
最后截图,通过四个点的位置计算出截图框的位置,然后放大对应原图大小的位置,得到在原图中的(x, y, width, height),最后通过官方提供的canvas接口截图。
特点
-
保证截图质量不会被压缩
-
截图框能够通过拖拽来调整大小
使用
假设我们的应用文件结构如下:
-
./
-
├── app.js
-
├── app.json
-
├── app.wxss
-
├── pages
-
│ └── index
-
│ ├── index.js
-
│ ├── index.json
-
│ ├── index.wxml
-
│ └── index.wxss
-
└── welCropper
-
├── welCropper.js
-
├── welCropper.wxml
-
└── welCropper.wxss
调用组件时,需要传入cropperData和cropperMovableItems,因为数据和事件都是绑定在Page上的,所以要避免使用组件里面已经被占用的命名。 /pages/index/index.wxml
-
<!-- 引入组件 -->
-
<import src="/welCropper/welCropper.wxml" />
-
-
<!-- 调用组件 -->
-
<template is="welCropper" data="{{data:cropperData, cropperMovableItems:cropperMovableItems}}"></template>
-
-
<!-- 用于选择图片,传入cropper中 -->
-
<button bindtap='selectTap'>select image</button>
/pages/index/index.js
-
// 获取显示区域长宽
-
const device = wx.getSystemInfoSync()
-
const W = device.windowWidth
-
const H = device.windowHeight - 50
-
-
let cropper = require('../../welCropper/welCropper.js');
-
-
console.log(device)
-
-
Page({
-
data: {
-
},
-
onLoad: function () {
-
var that = this
-
// 初始化组件数据和绑定事件
-
cropper.init.apply(that, [W, H]);
-
},
-
selectTap() {
-
var that = this
-
-
wx.chooseImage({
-
count: 1, // 默认9
-
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
-
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
-
success(res) {
-
const tempFilePath = res.tempFilePaths[0]
-
console.log(tempFilePath)
-
-
// 将选取图片传入cropper,并显示cropper
-
that.showCropper(tempFilePath, (resPath) => {
-
console.log("crop callback:" + resPath)
-
wx.previewImage({
-
current: '',
-
urls: [resPath]
-
})
-
-
// that.hideCropper() //隐藏,我在项目里是点击完成就上传,所以如果回调是上传,那么隐藏掉就行了,不用previewImage
-
})
-
}
-
})
-
}
-
})
最后引入组件的样式 /pages/index/index.wxss
-
@import "/welCropper/welCropper.wxss";
-
效果图
效果动图
截图
如果将movable-view显示出来是这样的:
显示movable-view后
源代码: Github:tomfriwel/welCropper,将welCropper文件夹复制到自己项目,引入调用就行了。
如果出现什么bug、问题或者建议可以告诉我,我会尽量改进。
|