获取未剪切的画布信息以传输到另一个画布

时间:2019-02-14 01:06:59

标签: javascript html5-canvas fabricjs

我需要将一个区域从一个画布复制到该区域的另一尺寸。该区域在一个或两个维度上都可能大于包含该区域的画布元素。我正在使用一个较大的区域来提高目标画布上图像的质量。

问题在于,使用src画布的ctx.drawImage()会导致从src到目标画布的剪切图像。

这是我们尝试过的一些技术。

  • 我们已缩放源画布的区域,以使其小于画布元素的宽度/高度,转换为源画布的左上角,然后将drawImage()与特定区域坐标可将数据直接复制到目标画布。这样最多只能得到模糊的图像,屏幕越小,画布越小,结果就越模糊。

  • 我们尝试了toDataURL,它实际上可以正常工作,并且可以正确显示不一定显示在canvas元素本身上的图像数据。但是,它的运行速度令人难以置信...我尝试过使用“ image / jpeg”并将质量降低到0.2-0.3,但是性能会导致严重的卡顿。

  • 我们尝试了ctx.getImageData(),将ImageData转换为BitmapImage并将其绘制到画布上。这是高性能的,但是不幸地导致裁剪问题。老实说,drawImage()可能实际上是在后台使用的……

    const ctx = destCanvas.getContext('2d');
    
    if (!ctx) {
        throw new Error('Failed to get context for static canvas, BUG!');
    }
    
    // Store state of srcCanvas viewport to be restored later & reset the viewport
    const originalViewport = srcCanvas.viewportTransform;
    const scaledViewport = [
        TEX_MULT,
        0,
        0,
        TEX_MULT,
        0,
        0
    ];
    srcCanvas.viewportTransform = scaledViewport;
    
    // Disable any elements that shouldn't be visible on the static canvas.
    if (srcCanvas.overlayImage) {
        srcCanvas.overlayImage.visible = false;
    }
    
    const hiddenForRender: fabric.Object[] = [];
    srcCanvas.getObjects().forEach((obj: fabric.Object) => {
        if (obj.excludeFromExport && obj.visible) {
            obj.visible = false;
            hiddenForRender.push(obj);
        }
    });
    
    // Store resized viewport for image calculations and rerender srcCanvas
    const renderViewport = srcCanvas.viewportTransform;
    srcCanvas.renderAll();
    
    // Copy the active canvas to the static canvas
    const srcCtx = srcCanvas.getContext();
    const rawImageData = srcCtx.getImageData(
        0,
        0,
        destCanvas.width * renderViewport[0] * window.devicePixelRatio,
        destCanvas.height * renderViewport[3] * window.devicePixelRatio
    );
    
    createImageBitmap(rawImageData).then(function(imgBitmap: ImageBitmap) {
        ctx.drawImage(
            imgBitmap,
            0,
            0,
            destCanvas.width * renderViewport[0] * window.devicePixelRatio,
            destCanvas.height * renderViewport[3] * window.devicePixelRatio,
            0,
            0,
            destCanvas.width * TEX_MULT,
            destCanvas.height * TEX_MULT
        );
    });
    

我还没有找到一种性能与getImageData或drawImage(srcCanvas)相同的技术,但是允许指定一个超出canvas元素的区域,而不会在目标画布中看到裁剪。真的不可能这样做吗?

0 个答案:

没有答案