缩小画布向下截止

时间:2018-01-24 07:27:33

标签: javascript css html5 canvas drawimage

向上缩放画布似乎工作正常,但缩小似乎会切断像素。我已经尝试移动周围的事情,并在没有仅内存的画布的情况下进行,但没有任何工作。我最好的猜测是画布的尺寸减小然后进一步缩小,因此画布数据不会覆盖整个画布尺寸。

// Create a newly scaled canvas from the original and then delete the original.
function ScaleCanvas(width, height, xScale, yScale) {

// Get the true overlay's current image data.
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

// Create an in-memory canvas at the new resolution.
const newCanvas = $("<canvas>")
    .attr("width", width)
    .attr("height", height)[0];

// Draw the true overlay's image data into the in-memory canvas.
newCanvas.getContext("2d").putImageData(imageData, 0, 0);

// Update the size/resolution of the true overlay.
ctx.canvas.width = width;
ctx.canvas.height = height;

// Scale the true overlay's context.
ctx.scale(xScale, yScale);

// Draw the in-memory canvas onto the true overlay.
ctx.drawImage(newCanvas, 0, 0);
}

这里有一个相关的问题,我得到了大部分逻辑:How to scale an imageData in HTML canvas?

画布在函数末尾是合适的分辨率/大小,但考虑到我有一些像素是透明的而其他像素是不透明的黑色,很明显缩小的画布右下角的像素不会产生期望的效果。

更新 这是一个jsfiddle来更好地说明问题。请注意,在缩小画布后,一个透明像素不会停留在画布的中间。

1 个答案:

答案 0 :(得分:1)

我没有设法重现,所以我也尝试放大和缩小画布,使用以下代码,一切看起来都很好:

HTML:

<!doctype html>
<html>
    <head>
        <style>
            canvas {
                border: 1px solid red;
            }
        </style>
    </head>
    <body>
        <canvas id="src" width="100" height="100"></canvas>
        <canvas id="dest" width="100" height="100"></canvas>


        <canvas id="src2" width="100" height="100"></canvas>
        <canvas id="dest2" width="100" height="100"></canvas>

        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script type="text/javascript" src="./main.js"></script>
    </body>
</html>

JavaScript的:

function scaleCanvas(srcCanvas, destCanvas, xScale, yScale) {
    var destCtx = destCanvas.getContext("2d");

    destCtx.scale(xScale, yScale);
    destCtx.drawImage(srcCanvas, 0, 0);
}

window.onload = function() {
    // Drawing on the source canvas for testing purpose
    var srcCanvas = document.querySelector("#src");
    var srcCtx = srcCanvas.getContext("2d");
    var destCanvas = document.querySelector("#dest");

    var image = new Image();
    image.src = 'https://yt3.ggpht.com/-gAb9nWOBObg/AAAAAAAAAAI/AAAAAAAAAAA/CAZq5pc1dnY/s100-c-k-no-mo-rj-c0xffffff/photo.jpg';
    image.onload = function() {
        srcCtx.drawImage(image, 0, 0);
    }
    // ----

    setTimeout(function() {
        scaleCanvas(srcCanvas, destCanvas, 0.5, 0.5);
    }, 1000);
};

结果:

enter image description here

希望它可以提供帮助。

编辑(06/02/2018):

我不太清楚你的问题。如果我是正确的,当您调整画布大小时,内容不会相应调整大小。因此,中心的某些内容可能不会出现在调整大小后应该出现的位置,而它必须位于已调整大小的内容的中心,以便保留原始比例。 为了说明,我在中间添加了一个中等大小的红色正方形(比透明像素更明显):

在调整大小之前:

enter image description here

调整大小后:

enter image description here

事实上,要实现缩减,您需要编辑 ScaleCanvas 调用:

由此:

ScaleCanvas(75, 75, .75, .75);

对此:

ScaleCanvas(100, 100, .75, .75);

仅更新比率,而不是画布的大小。

这是你得到的:

在调整大小之前:

enter image description here

调整大小后:

enter image description here

这是小提琴: jsfiddle

我希望我能很好地理解你的问题并解决这个问题。否则评论如下:)

编辑(13/02/2018):

好的,如果要调整画布及其内容的大小, ScaleCanvas 函数中新创建的画布必须与初始画布的大小相同。我更新了小提琴,以便您可以50%的比例多次调整画布大小:updated jsfiddle。注意画布的红色边框,表示画布的尺寸也减小了(不仅仅是视觉内容)。