【问题标题】:Scaling Canvas Down Is Getting Cutoff缩小画布正在被截断
【发布时间】:2018-07-03 04:09:51
【问题描述】:

放大画布似乎工作正常,但缩小似乎会切断像素。我已经尝试移动事物的顺序并在没有仅内存画布的情况下进行操作,但没有任何效果。我最好的猜测是画布被缩小然后进一步缩小,因此画布数据没有覆盖整个画布大小。

// 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 以更好地说明这个问题。请注意,画布缩小后,一个透明像素不会停留在画布中间。

【问题讨论】:

    标签: javascript css html canvas drawimage


    【解决方案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);
    };
    

    结果:

    希望对你有帮助。

    编辑(06/02/2018):

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

    调整大小之前:

    调整大小后:

    其实要实现缩小,你需要编辑你的ScaleCanvas调用:

    从这里:

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

    到这里:

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

    只更新比例,不更新画布大小。

    这是你得到的:

    调整大小之前:

    调整大小后:

    这是小提琴: jsfiddle

    我希望我已经很好地理解了您的问题,并且这可以解决它。否则在下面评论:)

    编辑(13/02/2018):

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

    【讨论】:

    • 感谢您的帮助。这是一个更好地说明问题的jsfiddle。注意缩小jsfiddle.net/jmho907u后透明像素如何不在中间
    • @m4gik 谢谢你的提琴,我编辑了我之前的答案
    • 实际上,这似乎产生了 99% 的预期效果。如果以这种方式缩小画布,那么画布元素的实际宽度和高度仍然是原始的更大尺寸。有什么方法可以在保持相同行为的同时向下调整画布的大小?
    • @m4gik 我编辑了我的编辑 :> 我希望它是你要找的!祝你有美好的一天
    • 非常感谢!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    猜你喜欢
    • 2019-08-06
    • 1970-01-01
    • 2014-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多