某些机型上,截图生成的报告,存到手机中会有黑边的问题;不管是设置scale
缩放比为1,画布的宽高为截取内容的width、height,都没有办法解决;
解决方式
获取图片的像素信息
我们创建一个canvas,渲染图片,然后通过 getImageData
方法拿到图片信息。 drawImage: 绘制图像,将图片绘制到画布上 getImageData: 返回一个ImageData对象,获取像素数据
javascript
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const image = new Image();
image.onload = draw;
image.src = url;
// image.src = dom.toDataURL(); // 导出图片
image.crossOrigin = "Anonymous";
function draw() {
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const { data, width, height } = imageData;
}
打印出来的图片信息为:
width
: 图片宽度;height
: 图片高度;colorSpace
: 色彩模式,这里是srgb;ps:
颜色范围的色域标准,sRGB色域应用广泛,包括Windows、Photoshop、大部分浏览器、显示屏等的默认配置都是sRGB
data
: 色彩信息,可以被使用作为查看初始像素数据。每个像素用 4 个 1bytes 值
(按照红,绿,蓝和透明值的顺序; 这就是"RGBA"格式) 来代表。;
我们重点来看看data:
- data是个数组;
- 每4个元素构成一个RGBA像素块;
- 每个元素的值范围都是0-255;
- RGB代表红绿蓝三原色;
- A代表透明度(0是完全透明,255是不透明);
假如存在两个,都是黑色的像素点
,宽度为2
, 高度为1
,值为[0, 0, 0, 255, 0, 0, 0, 255]
。 那么他的格式就是:
javascript
{r: 0, g: 0, b: 0, a: 255}, {r: 0, g: 0, b: 0, a: 255}
获取像素块索引
我们已知width
和height
,col为列,row为行,两层循环构造每一个网格,便利所有网格的像素,如果有色彩则设置裁剪的起点和终点。
索引值从 0 到 (高度× 宽度 ×4)-1 例如,要读取图片中位于第 50 行,第 200 列的像素的蓝色部份,你会写以下代码: (50 * (imageData.width * 4)) + (200 * 4)) + 2 根据行、列读取某像素点的 R/G/B/A 值的公式: ((50 * (imageData.width * 4)) + (200 * 4)) + 0/1/2/3;
javascript
for (let col = 0; col < width; col++) {
for (let row = 0; row < height; row++) {
// 当前像素块相对于图片的索引位置
const pxIndex = (row * width + col) * 4;
}
}
获取每个像素块的RGBA信息
javascript
const pxStartIndex = pxIndex;
const pxData = {
r: data[pxStartIndex],
g: data[pxStartIndex + 1],
b: data[pxStartIndex + 2],
a: data[pxStartIndex + 3]
};
计算裁剪的起点和终点坐标
我们需要将png图片周围的透明区域去掉。所以先判断是否存在色彩:
javascript
// 不透明
const colorExist = pxData.a !== 0;
起点和终点初始化值一定要先设置成极限值,也就是两点互换位置,
javascript
let startX = width,
startY = height,
endX = 0,
endY = 0;
startX坐标
取当前col和startX的最小值;endX坐标
取当前col和endX的最大值;startY坐标
取当前row和startY的最小值;endY坐标
取当前row和endY的最大值;
如果之前初始化的时候没有取极限,使用Math.min判断的时候一直会是0;
javascript
if (colorExist) {
startX = Math.min(col, startX);
endX = Math.max(col, startX);
startY = Math.min(row, startY);
endY = Math.max(row, endY);
}
根据计算的起点终点进行裁剪
javascript
const cropCanvas = document.createElement("canvas");
const cropCtx = cropCanvas.getContext("2d");
cropCanvas.width = endX - startX;
cropCanvas.height = endY - startY;
cropCtx.drawImage(
image,
startX,
startY,
cropCanvas.width,
cropCanvas.height,
0,
0,
cropCanvas.width,
cropCanvas.height
);
// 裁剪后的图像字符串
console.log(cropCanvas.toDataURL());