The small program canvas 2d is a solution for drawing high-definition pictures. It can generate 10M posters at most, which solves the problem of failure to generate pictures under android with too large width and height.


As we all know, wechat canvas needs to call this interface to generate pictures. If this interface wants to generate high-definition pictures and solve the problem of font blur, it needs destWidth * dpr.

The width and height of the original canvas is too large, coupled with destWidth * dpr, will inevitably lead to the width and height of destWidth is too large, which may lead to Android failure in generating pictures.

Since this interface doesn't work, don't use it.

In another way, the applet canvas type=2d interface supports a relatively comprehensive basic library. According to the official introduction, canvas type=2d basically refers to the interface of H5. Then, the methods available for H5 should be available here.

canvas 2d

According to the example provided by wechat:

  onReady() {
    const query = wx.createSelectorQuery()'#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 if you want to draw high definition without blurring the text, you need to set canvas Width and canvas Height is explicitly set and multiplied by dpr (wxss should also be set to normal width and height), and the drawing context ctx needs to be scaled to dpr.

ctx scales dpr so that the rendering density is consistent with the pixel density. If something doesn't want to scale the drawing, you can set ctx Settransform (1, 0, 0, 1, 0, 0) restores the scaling of the drawing context.

Now draw boldly, because the density of the drawing is equal to the pixel density, so the actual display is very clear. The width and height of canvas 2d can be set larger, but it can not be set too large. If the width and height are too large, there will be a crash problem under Android.

There is no problem with the width and height of 1500800 in the real machine test. Due to the pixel density, if dpr = 3, it is actually 45002400

So such a large width and height is using Wx When canvastotempfilepath is used, it is likely to cause the image generation failure of Android machine. At this time, an artifact should be sacrificed:

_canvas_.toDataURL(_type_, _encoderOptions_);

HTMLCanvasElement. The todataurl () method returns a file containing a picture display data URI . You can use the type parameter to its type. The default is PNG Format. The resolution of the picture is 96 DPI.

  • type is optional. The image format is "image/png" by default
  • Encoderioptions is optional. When the specified image format is , image/jpeg or , image/webp, you can select the quality of the image from 0 to 1. If it exceeds the value range, the default value of 0.92 will be used. Other parameters are ignored.

You can use canvas Todataurl() gets a data URI with image display, and deletes the header data:image/jpeg;base64, get a pure base64 image data.

Now that you have the picture data, you can write the data into a picture.

  • Open the file manager provided by wechat
  • Convert base64 data to buffer
  • Pass FSM WriteFile writes the file to the user storage space Wx env. USER_ DATA_ Path location.
  • filePath is a picture
  • Since the storage space of wechat is only 10M, it can support 10M image generation at most, which can meet most needs.
const filePath = `${wx.env.USER_DATA_PATH}/cover.jpg`;
let fsm = wx.getFileSystemManager();
let buffer = wx.base64ToArrayBuffer(bodyData);
     filePath: filePath,
     data: buffer,
     encoding: 'binary',
     success() {
         console.log('---success---', filePath);
     fail(error) {

Don't forget to clear the storage space after use, otherwise you won't be able to save it next time

  removeLocalFile() {
    // Note that the file storage space is 10M
    // In order to keep enough space, the files in the root directory are deleted
    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()) {
    } catch (e) {

You can empty different files according to your needs. There is no need to empty all the contents of the root directory

At this point, you can happily use canvas 2D to draw high-definition pictures.

Tags: Javascript html5 Mini Program canvas

Posted by phppaper on Sat, 14 May 2022 11:22:10 +0300