缩减 Canvas 会被截断
Scaling Canvas Down Is Getting Cutoff
放大 canvas 似乎工作正常,但缩小似乎会切断像素。我试过移动事物的顺序并在没有仅内存 canvas 的情况下进行,但没有任何效果。我最好的猜测是 canvas 正在缩小然后进一步缩小,因此 canvas 数据没有覆盖整个 canvas 大小。
// 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?
函数末尾的canvas是合适的resolution/size,但考虑到我有一些像素透明而另一些不透明的黑色,很明显右边和右边的像素缩小后的底部 canvas 没有产生预期的效果。
更新
这里有一个 jsfiddle 可以更好地说明问题。请注意,canvas 缩小后,一个透明像素不会留在 canvas 的中间。
我没能重现,所以我也尝试放大和缩小 canvas 并且使用以下代码一切看起来都很好:
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);
};
结果:
希望对您有所帮助。
编辑(2018 年 6 月 2 日):
我不确定是否完全理解您的问题。如果我是正确的,当您调整 canvas 大小时,内容不会相应地调整大小。因此,中心的某些内容在调整大小后可能不会出现在应有的位置,而它必须位于调整后的内容的中心,以便保持原始比例。
为了说明,我在中间添加了一个中等大小的红色方块(比透明像素更明显):
调整大小前:
调整大小后:
事实上,要实现缩小,您需要编辑您的 ScaleCanvas 调用:
来自这里:
ScaleCanvas(75, 75, .75, .75);
为此:
ScaleCanvas(100, 100, .75, .75);
只更新比例,不更新canvas的大小。
这是你得到的:
调整大小前:
调整大小后:
这是 fiddle:
jsfiddle
希望我已经很好地理解了您的问题,并且希望这可以解决问题。否则在下面评论 :)
编辑(13/02/2018):
好的,如果你想同时调整 canvas 和它的内容的大小,ScaleCanvas 函数中新创建的 canvas 必须是相同的大小作为初始canvas。我更新了 fiddle,以便您可以多次调整 canvas 的大小,比例为 50%:updated jsfiddle。请注意 canvas 的红色边框,这表明 canvas 的尺寸也减小了(不仅是视觉内容)。
放大 canvas 似乎工作正常,但缩小似乎会切断像素。我试过移动事物的顺序并在没有仅内存 canvas 的情况下进行,但没有任何效果。我最好的猜测是 canvas 正在缩小然后进一步缩小,因此 canvas 数据没有覆盖整个 canvas 大小。
// 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?
函数末尾的canvas是合适的resolution/size,但考虑到我有一些像素透明而另一些不透明的黑色,很明显右边和右边的像素缩小后的底部 canvas 没有产生预期的效果。
更新 这里有一个 jsfiddle 可以更好地说明问题。请注意,canvas 缩小后,一个透明像素不会留在 canvas 的中间。
我没能重现,所以我也尝试放大和缩小 canvas 并且使用以下代码一切看起来都很好:
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);
};
结果:
希望对您有所帮助。
编辑(2018 年 6 月 2 日):
我不确定是否完全理解您的问题。如果我是正确的,当您调整 canvas 大小时,内容不会相应地调整大小。因此,中心的某些内容在调整大小后可能不会出现在应有的位置,而它必须位于调整后的内容的中心,以便保持原始比例。 为了说明,我在中间添加了一个中等大小的红色方块(比透明像素更明显):
调整大小前:
调整大小后:
事实上,要实现缩小,您需要编辑您的 ScaleCanvas 调用:
来自这里:
ScaleCanvas(75, 75, .75, .75);
为此:
ScaleCanvas(100, 100, .75, .75);
只更新比例,不更新canvas的大小。
这是你得到的:
调整大小前:
调整大小后:
这是 fiddle: jsfiddle
希望我已经很好地理解了您的问题,并且希望这可以解决问题。否则在下面评论 :)
编辑(13/02/2018):
好的,如果你想同时调整 canvas 和它的内容的大小,ScaleCanvas 函数中新创建的 canvas 必须是相同的大小作为初始canvas。我更新了 fiddle,以便您可以多次调整 canvas 的大小,比例为 50%:updated jsfiddle。请注意 canvas 的红色边框,这表明 canvas 的尺寸也减小了(不仅是视觉内容)。