Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在画布上重画而不模糊地调整大小?_Javascript_Css_Html_Canvas - Fatal编程技术网

Javascript 如何在画布上重画而不模糊地调整大小?

Javascript 如何在画布上重画而不模糊地调整大小?,javascript,css,html,canvas,Javascript,Css,Html,Canvas,调整画布元素的大小(通过样式更改)时,我还希望缩放画布绘制的图像。我不能只更改高度/宽度,因为这会导致画布自行清除,所以我会: 创建临时画布元素 将当前画布的图像绘制到该临时画布上 调整当前画布的大小 将临时画布的图像绘制回当前画布,但缩放到新大小 这会导致一些模糊-在多次调整大小后非常明显(例如:拖动以调整大小时)。我如何做到这一点而不模糊 编辑:关闭图像平滑(context.webkitImageSmoothingEnabled=false;)并不能解决问题,它只是使图像越来越锯齿状,直到多

调整画布元素的大小(通过样式更改)时,我还希望缩放画布绘制的图像。我不能只更改高度/宽度,因为这会导致画布自行清除,所以我会:

  • 创建临时画布元素
  • 将当前画布的图像绘制到该临时画布上
  • 调整当前画布的大小
  • 将临时画布的图像绘制回当前画布,但缩放到新大小
  • 这会导致一些模糊-在多次调整大小后非常明显(例如:拖动以调整大小时)。我如何做到这一点而不模糊

    编辑:关闭图像平滑(
    context.webkitImageSmoothingEnabled=false;
    )并不能解决问题,它只是使图像越来越锯齿状,直到多次调整大小后图像看起来与原始图像完全不同

    在调整大小事件时调用:

        var tmpCanvas = null;       
    
        //Make a temporary canvas
        tmpCanvas = document.createElement( "canvas" );
    
        //Set its size to be equal
        tmpCanvas.height = originalCanvas.height;
        tmpCanvas.width = originalCanvas.width;
    
        //Draw our current canvas onto it
        tmpCanvas.getContext( "2d" ).drawImage( originalCanvas, 0, 0 );
    
        //Set new dimensions
        originalCanvas.width = originalCanvas.offsetWidth;
        originalCanvas.height = originalCanvas.offsetHeight;
    
        var originalContext = originalCanvas.getContext( "2d" );
    
        //Set background and colors
        originalContext.fillStyle = "#ffffff";
        originalContext.strokeStyle = "#000000";
    
        //Set paintbrush
        originalContext.lineWidth = 4;
        originalContext.lineCap = "round";
    
        //Fill background as white
        originalContext.fillRect( 0, 0, originalCanvas.width, originalCanvas.height );
    
        //We have a saved signature
        if ( SignatureCanvas.hasSignature === true )
        {
            //Draw it back but scaled (results in blurred image)
            originalContext.drawImage( tmpCanvas, 0, 0, tmpCanvas.width, tmpCanvas.height, 0, 0, originalCanvas.width, originalCanvas.height );
    
            /** 
             * This results in a blurred image as well
             //Draw it back but scaled
             originalContext.scale( originalCanvas.width / tmpCanvas.width, originalCanvas.height / tmpCanvas.height );
             originalContext.drawImage( tmpCanvas, 0, 0, tmpCanvas.width, tmpCanvas.height, 0, 0, tmpCanvas.width, tmpCanvas.height );
             */
        }
    

    有没有办法获得笔划和“缩放”所有这些点并重新绘制?

    实际上是重新绘制图像,而不是从原始画布获取渲染图像。我的意思是,执行与原始画布相同的逻辑,但所涉及的点会缩放到新的大小

    如果可以,可以考虑改用SVG。它的性质决定了它的规模

    编辑:我想到的另一个选择是简单地使用一个巨大的画布开始。缩小尺寸比增大尺寸看起来更好,尤其是在平滑的情况下。

    编辑II:最初的答案是不相关的,尽管我所做的评论是相关的,现在我正在推广它并将其编辑为一个答案……而且我给出的答案也不是那么好**

    当然,如果放大光栅图形,即从像素尺寸较小的图像创建像素尺寸较高的图像,则会得到模糊图像。通过放大,您可以使低分辨率图片具有高分辨率,但没有高分辨率细节

    除非您对光栅图像进行多个附加假设(例如,您将看到的唯一灰度位于图像边缘),否则绝对无法避免这种模糊,或者角点只能出现在明显的拐点处,其中连接曲线的切线之间的角度必须为100度或更小。基本上,您必须提供额外的信息,以便您的高分辨率图像可以“填充”细节。它与从光栅反向工程SVG并没有太大区别

    因此,您似乎想要模拟的是缩放矢量图形,其中唯一的解决方案是保存命令、绘制SVG或绘制Stuart Branham建议的更大画布


    **我最初提出,调用
    drawImage
    会扭曲像素,即使它没有缩放,而且最好使用实际的像素数据。如果这是真的,我找不到证据,但那无关紧要,因为他希望自己的图像放大,而不模糊……这是不可能的,正如我刚才提到的。

    我该怎么做?在第一张画布上绘制的图像是由用户完成的,因此我事先不知道它是什么。有没有办法从画布上绘制的图形中获取信息并缩放这些点并重新绘制它们?您需要存储用户执行的命令(我猜是哪些点绘制的)并以新的大小重放该逻辑。您需要某种向量表示来清晰地调整大小。否则,您只需调整光栅图像的大小,而这看起来只是调整了大小。画布只是画布;它不像SVG那样存储层或组件。使用
    getImageData
    中的数据远不简单。返回的是所有像素的红、绿、蓝和alpha值的数组。我该如何缩放?对不起,我不清楚你是否在缩放。当然,如果你缩放光栅图形,你会得到模糊的图像。除非您对光栅图像进行多个附加假设(例如,您看到的唯一灰度是图像边缘、构成角点的内容等),否则根本无法解决此问题。您似乎想要模拟的是缩放矢量图形,其中唯一的解决方案是保存命令或使用Stuart Branham建议的SVG。您不正确地认为这是不可能的。只要知道创建的路径,就可以缩放这些路径并在新大小的画布上重新绘制它们。这将生成一个不模糊、缩放的副本。更多信息请参见此处:从光栅图像!如果您使用的是创建的路径,那么您没有使用光栅图像,是吗?光栅图像是像素,并且只有像素。如果您使用的是路径,那么实际上就是使用矢量图形。