关于javascript:小程序canvas-2d绘制高清图片的解决方案最大可生成10M海报解决过大宽高安卓下生成图片失败的问题

41次阅读

共计 2147 个字符,预计需要花费 6 分钟才能阅读完成。

wx.canvasToTempFilePath

家喻户晓,微信 canvas 生成图片要调用这个接口,而这个接口如果想生成高清的图片,解决字体含糊问题则须要destWidth * dpr

原始 canvas 的宽高过大,再加上 destWidth * dpr 必然会导致 destWidth 的宽高过大,从而可能导致安卓在生成图片时失败。

既然这个接口行不通,那么就不应用这个接口啦。

换个思路,小程序 canvas type=2d 接口,反对的根底库也比拟全面了,依据官网介绍说,canvas type=2d 基本上参照了 H5 的接口,那么,H5 可用的办法,在这里应该能够应用了。

canvas 2d

依据微信提供的示例:

Page({onReady() {const query = wx.createSelectorQuery()
    query.select('#myCanvas')
      .fields({node: true, size: true})
      .exec((res) => {const canvas = res[0].node
        const ctx = canvas.getContext('2d')
        const dpr = wx.getSystemInfoSync().pixelRatio
        canvas.width = res[0].width * dpr
        canvas.height = res[0].height * dpr
        ctx.scale(dpr, dpr)
        ctx.fillRect(0, 0, 100, 100)
      })
   }
})

canvas 2d 要想绘制高清,同时文字不含糊,则须要将 canvas.width 和 canvas.height 显式的设置并乘 dpr(wxss 也要失常设置失常宽高),同时须要将绘制上下文 ctx 缩放 dpr。

ctx 缩放 dpr 是为了让绘制密度与像素密度保持一致。如果某些货色不想缩放绘制,则能够设置 ctx.setTransform(1, 0, 0, 1, 0, 0)还原绘制上下文的缩放。

当初大胆绘制吧,因为绘制的密度等于像素密度,所以理论显示是十分清晰的,canvas 2d 的宽高能够设置较大,但不能设置过大哦,过大的宽高,在安卓下会有 crash 的问题。

真机测试 1500800 的宽高是齐全没有问题的,因为像素密度的起因,如果 dpr = 3,实际上是 45002400

那么这么大的宽高在应用 wx.canvasToTempFilePath 时很有可能造成安卓真机生成图片失败,这时候就应该祭出一个神器:

_canvas_.toDataURL(_type_, _encoderOptions_);

HTMLCanvasElement.toDataURL() 办法返回一个蕴含图片展现的 data URI。能够应用 type 参数其类型,默认为 PNG 格局。图片的分辨率为 96dpi。

  • type 可选,图片格式,默认为 image/png
  • encoderOptions 可选,在指定图片格式为 image/jpeg 或 image/webp 的状况下,能够从 0 到 1 的区间内抉择图片的品质。如果超出取值范畴,将会应用默认值 0.92。其余参数会被疏忽。

能够通过 canvas.toDataURL() 失去一个含图片展现的 data URI,通过删除头 data:image/jpeg;base64, 失去一个纯 base64 的图片数据。

既然失去图片数据了,那么,将数据写入成图片就能够了。

  • 关上微信提供的文件管理器
  • 将 base64 数据转换为 buffer
  • 通过 fsm.writeFile 将文件写入用户存储空间 wx.env.USER_DATA_PATH 地位。
  • filePath 就是图片啦
  • 因为微信的存储空间只有 10M,所以最大能够反对 10M 的图片生成哦,能够满足少数需要了。
const filePath = `${wx.env.USER_DATA_PATH}/cover.jpg`;
let fsm = wx.getFileSystemManager();
let buffer = wx.base64ToArrayBuffer(bodyData);
fsm.writeFile({
     filePath: filePath,
     data: buffer,
     encoding: 'binary',
     success() {console.log('---success---', filePath);
     },
     fail(error) {console.error(error);
     }
 });

应用完别忘了清理存储空间,不然下次存不进去

  removeLocalFile() {
    // 留神,文件存储空间为 10M
    // 为了放弃空间够用,删除了根目录下的文件
    const fsm = wx.getFileSystemManager();
    try {const ls = fsm.readdirSync(wx.env.USER_DATA_PATH);
      ls.forEach(d => {let path = `${wx.env.USER_DATA_PATH}/${d}`;
        let stats = fsm.statSync(path);
        if (stats.isFile()) {fsm.unlinkSync(path);
        }
      });
    } catch (e) {console.log(e);
    }
  }

能够依据需要清空不同的文件,没必要清空根目录所有内容

至此,能够欢快的应用 canvas2d 绘制高清图片了。

正文完
 0