Сохранение содержимого OffscreenCanvas на диск в формате PNG в Electron - PullRequest
1 голос
/ 05 марта 2020

Я использую canvg для рендеринга SVG на холсте и загрузки его в формате PNG из браузера. Вот рабочий фрагмент машинописного кода, основанный на их документах.

    const canvas = new OffscreenCanvas(this.width, this.height);
    const ctx = canvas.getContext('2d');
    const v = await Canvg.from(ctx!, this.svg.innerHTML, presets.offscreen());

    // Render only first frame, ignoring animations and mouse.
    await v.render();

    const blob = await canvas.convertToBlob();
    const pngUrl = URL.createObjectURL(blob);

    var img = new Image();
    img.src = pngUrl;

    const a = document.createElement("a");
    a.href = pngUrl;
    a.download = "svgexport.png";
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);

Однако я хочу, чтобы это работало в Electron. Вместо того, чтобы загружать PNG, я хочу записать его на диск с помощью модуля fs. Я пробовал несколько способов записи содержимого blob в файл PNG, однако сохраненный файл не является допустимым файлом PNG. Я также попробовал электроны nativeImage. Но ни один из его API (createFromBuffer, createFromBitmap, createFromDataURL) не дает желаемого результата.

Есть идеи?

1 Ответ

1 голос
/ 05 марта 2020

Хорошо, я нашел способ достижения этого sh. Из большого двоичного объекта, полученного от OffscreenCanvas, я создаю объект Image, затем отображаю его в canvas, затем я могу записать URL-адрес данных с этого холста в файл на диске, и он дает мне действительный PNG. Вот код

    const canvas = new OffscreenCanvas(this.width, this.height);
    const ctx = canvas.getContext('2d');
    const v = await Canvg.from(ctx!, this.svg.innerHTML, presets.offscreen());

    // Render only first frame, ignoring animations and mouse.
    await v.render();

    const blob = await canvas.convertToBlob();
    const pngUrl = URL.createObjectURL(blob);

    var img = new Image();
    img.onload = () => {
        var canvas = document.createElement('canvas');
        var context = canvas.getContext('2d');
        canvas.width = this.width;
        canvas.height = this.height;
        context!.drawImage(img, 0, 0);

        let dataURL = (canvas as HTMLCanvasElement).toDataURL();
        const base64Data = dataURL.replace(/^data:image\/png;base64,/, "");
        fs.writeFile("test5.png", base64Data, 'base64', function (err) {
            console.log(err);
        });
    }
    img.src = pngUrl;

Хотелось бы посмотреть, есть ли у кого-нибудь лучшее предложение.

...