Canvas.toDataURL 用不了咋办?

共 3083字,需浏览 7分钟

 ·

2021-08-12 20:09

事由是这样的,接到一个截图需求(以 base64 输出),但是在某个环境下,Canvas.toDataURL 这个接口返回的数据是错误的。
为此,写一篇文章记录一下,如何绕过 Canvas.toDataURL ,生成 base64 字符串。
以下为 Cocos官网文档中给出的截图事例代码。
https://docs.cocos.com/creator/manual/zh/render/camera.html#%E6%88%AA%E5%9B%BE
官网中的截图代码
幸运的是 readPixels() 能读到位图的像素信息。
程序就是处理输入和输出的过程,为此,明确我们的输入输出。
  • 输入:data: Uint8Array 位图信息 和 图片宽高。
  • 输出:带有图片信息的base64字符串。(可将该字符串放浏览器中的地址栏,会返回一张图片)
经思考🤔一番,决定采用以下几步实现:
  • 像素数据 -> 转 JPG 数据 -> 转 base64
如何转 JPG 格式?按照厂里的方法,应该去了解其文件格式如何生成,需要什么头文件信息,关于JPEG相关内容可参考wiki :
https://en.wikipedia.org/wiki/JPEG
但🥚,在思考前,可以考虑是否有前任👩的轮子。毕竟时间也是一种成本。
很快,很有型地在大型交友网站 github 中找到了前人留下的轮子。
https://github.com/jpeg-js/jpeg-js/blob/master/lib/encoder.js
这是 JavaScript 的代码,白玉无冰这里操作的是直接拷贝出来,放到一个 TypeScript 代码中,导出 encodeJPG 方法。
搬运与改造 jpeg-js
再参考 jpeg-js 中的实例代码,组织一下,很快就生成了 JPEG 的数据。
像素数据 转 JPEG 数据
再把JPEG 的数据中 Uint8Array 转 base64
Uint8Array 转 base64
但发现截图反了。
截图反了
最后,再对原来的数据翻转一下,完整的核心代码如下:
// 这样我们就能从 RenderTexture 中获取到数据了
let data = texture.readPixels();
let width = texture.width;
let height = texture.height;
// 接下来翻转y的数据
const flipYData = new Uint8Array(width * height * 4);
let rowBytes = width * 4;
for (let row = 0; row < height; row++) {
    let startRow = height - 1 - row;
    let start = startRow * width * 4;
    for (let i = 0; i < rowBytes; i++) {
        flipYData[row * width * 4 + i] = data[start + i];
    }
}
// 准备生成 jpegImageData
const rawImageData = {
    data: flipYData,
    width: width,
    height: height,
};
const jpegImageData = encodeJPG(rawImageData, 50);
// jpeg -> base64
function uint8ToString(buf{
    var i, length, out = '';
    for (i = 0, length = buf.length; i < length; i += 1) {
        out += String.fromCharCode(buf[i]);
    }
    return out;
}
const base64 = btoa(uint8ToString(jpegImageData.data));
cc.warn('base64'"data:image/jpg;base64," + base64);

完整代码工程:

https://github.com/baiyuwubing/cocos-creator-examples/tree/master/2.4.x/assets/demo06

以上为白玉无冰使用 Cocos Creator 2.4 实现 "截图生成 base64" 的过程分享,点击【阅读原文】发现更多白玉无冰实用教程。

往期精彩

浏览 19
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报