记录Canvas用于LODOP打印的解决过程

工作中遇到用canvas绘制了图片,需要打印出来的需求。由于设备限制遇到了不少奇葩问题。在解决过程中学会了不少知识,在此记录下,希望能对同样遇到此类问题的朋友有所帮助。

将 Canvas 转为 png

首先要知道LODOP直接打印canvas是打印不出来的,所以我们需要转为图片。
假设div中有一个绘制完的canvas,最基本的方式就是:获取canvas内容转为base64码,然后将canvas替换为一个img图片。

function toImage () {
    var canvas = $('#app canvas')
    if (!canvas) return
    var url = canvas[0].toDataURL()
    $('#app').html("<img src='" + url + "'>")
},

这样,直接打印网页就可以打印出我们用canvas绘制的图片了。

LODOP.PRINT_INIT("测试页");
LODOP.ADD_PRINT_HTM("0mm", "0mm", "100%", "100%", html1);
LODOP.PREVIEW();

toDataURL 方法还可以转为其他格式的图片,如 jpeg。具体请看MDN
在使用第一个方法时遇到一个问题:由于canvas所画内容较大,导致base64码有40000+的长度。在64位系统中可以正常在打印预览界面显示图片,但是在32位系统中 LODOP 打印预览界面图片显示为红叉。

直接解析base64码

在查阅了官网之后找到一种直接显示base64的方法:

LODOP.PRINT_INIT("测试页");
var canvas = $('#app canvas')
var img = canvas[0].toDataURL()
LODOP.ADD_PRINT_IMAGE("0mm", "0mm", "100%", "100%", img)
LODOP.PREVIEW();

这种方法下,64位和32位系统中都在LODOP预览界面中显示出了图片。
但是,问题又来了,其他打印机都可以,但是 HP 打印机却显示不出图片。

本地缓存图片

于是我就想,难道还是base64码太长,惠普打印机不识别,于是又试着使用本地缓存策略。

function toImage () {
    var canvas = $('#app canvas')
    if (!canvas) return
    var src = canvas[0].toDataURL()
    src = src.replace(/^data:image\/(png|jpeg);base64,/, "");
    console.log(src)
    var blob = base64toBlob(src)
    var url = URL.createObjectURL(blob)
    console.log(url)
    $('#app').html("<img src='" + url + "'>")
}

function base64toBlob (base64Data, contentType) {
    contentType = contentType || '';
    var sliceSize = 1024;
    var byteCharacters = atob(base64Data);
    var bytesLength = byteCharacters.length;
    var slicesCount = Math.ceil(bytesLength / sliceSize);
    var byteArrays = new Array(slicesCount);

    for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
        var begin = sliceIndex * sliceSize;
        var end = Math.min(begin + sliceSize, bytesLength);

        var bytes = new Array(end - begin);
        for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
            bytes[i] = byteCharacters[offset].charCodeAt(0);
        }
        byteArrays[sliceIndex] = new Uint8Array(bytes);
    }
    return new Blob(byteArrays, { type: contentType });
}

如此一来,图片从 base64 转为了 blob,再有 blob 转为 url 。url结果如下:

blob:http://localhost:3457/cb7d016a-0862-48a5-8b12-740569e643a9

结果发现在 LODOP 打印预览中出现的还是红叉。我猜测可能是由于插件无法读取浏览器缓存文件。

本地图片

好像只有本地图片一途了。但查阅资料后发现在浏览器中保存图片都会走下载那一套流程,即弹出框让用户下载图片。
下载图片的方法代码如下:

function saveBase64AsFile(base64, fileName) {
    var link = document.createElement("a");

    link.setAttribute("href", base64);
    link.setAttribute("download", fileName);
    link.click();
}

var canvas = $('#app canvas')
var img = canvas[0].toDataURL()
saveBase64AsFile(img, 'hello.png')

弹出下载框已经宣布了该方案的失败了。这里记录下显示本地图片的方式:

<img src="file://C:/Users/VioletJack/Downloads/hello.png"/>

所以,这个方案也失败了~

最后

最后解决图片问题的方案是:将 base64 码通过 post 方式传给后端,后端解析 base64 码,在服务器端生成以 Guid 命名的图片。然后后端返回给前端图片地址。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值