0

I have this image with a scaling feature as you see on the image below, for this I set the scale to 25% and draw a rectangle. enter image description here

But when I try to go back to 100%, the rectangle seems to be blurry.enter image description here

How can I make the rectangle not blurry and have the same appearance as the 2nd rectangle beside of it when I'm changing the scale?

  var paintPolygon = function () {
    /* Drawing on Paint App */
    var size = parseInt($("#zoom").val());
    var defaultSize = 5;
    var computedSize = (size / 100) * defaultSize;
    tmp_ctx.lineWidth = computedSize;

} In the code above I am adjusting the lineWidth of the drawing based on the scale.

When the user finished drawing, I am saving the canvas to a global temporary image variable

var tmpImg = new Image();
    tmpImg.width = $("#imgFile").width();       
    tmpImg.height = $("#imgFile").height();     
    tmpImg.src = canvas.toDataURL();


tmp_canvas.addEventListener('mouseup', function () {
    tmp_canvas.removeEventListener('mousemove', onPaint, false);

    if (currentTool == "eraser") {
        ppts = [];
        $("#tmp_canvas").css('cursor', 'default');
    }
    else {
        ctx.globalCompositeOperation = 'source-over';
        // Writing down to real canvas now
        ctx.drawImage(tmp_canvas, 0, 0);
        tmpImg.width = $("#imgFile").width();       
        tmpImg.height = $("#imgFile").height();     
        tmpImg.src = canvas.toDataURL();
        // Clearing tmp canvas
        tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
        // Emptying up Pencil Points
        ppts = [];
    }
}, false);

Then for the scaling event.

function onPanChange() {
    var size = $("#zoom").val();
    $("#imgFile").css({ "height": size + "%", "width": size + "%" });
    var imgH = $("#imgFile").height(), imgW = $("#imgFile").width();
    var canvas = document.querySelector('#clientAnnotation');
    var ctx = canvas.getContext('2d');
    canvas.width = imgW;
    canvas.height = imgH;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(tmpImg, 0, 0, canvas.width, canvas.height);
}

So every time we changed the scale we always draw the image. I know that every time we're making the scale bigger, the drawing gets more blurry. Just asking for help on how can we make the rectangle from the left side will look as same as the rectangle on the right side even when we scale either bigger or smaller.

If I add this code

ctx.imageSmoothingEnabled = false;

The drawing would look like this enter image description here

Sorry for my bad English, Please let me know if there is something that it is not clear and needs to explanation further. Any help will be super appreciated.

Thank you.

Vince
  • 45
  • 5

1 Answers1

0

Simply turn off canvas' anti-aliasing for images - unfortunately this property is still vendor prefixed so here are the variations:

context.webkitImageSmoothingEnabled = false;
context.mozImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false; /// future

then draw the image.

Optionally for older versions and browsers which hasn't implemented this yet, you can use CSS instead:

canvas {
    image-rendering: optimizeSpeed;             // Older versions of FF
    image-rendering: -moz-crisp-edges;          // FF 6.0+
    image-rendering: -webkit-optimize-contrast; // Webkit (non standard naming)
    image-rendering: -o-crisp-edges;            // OS X & Windows Opera (12.02+)
    image-rendering: crisp-edges;               // Possible future browsers.
    -ms-interpolation-mode: nearest-neighbor;   // IE (non standard naming)
}

var img = document.createElement('img');
img.onload = drawExamples;
img.src = 'https://i.imgur.com/ramzOwQ.png';

function drawExamples() {

    var ctxS = smoothing.getContext('2d'),
        ctxNS = nosmoothing.getContext('2d');
    
    ctxNS.webkitImageSmoothingEnabled = false;
    ctxNS.mozImageSmoothingEnabled = false;
    ctxNS.imageSmoothingEnabled = false; //future

    ctxS.drawImage(img, 10,10);
    ctxNS.drawImage(img, 10,10);

    ctxS.drawImage(img, 80,10, img.width*3, img.height*3);
    ctxNS.drawImage(img, 80,10, img.width*3, img.height*3);
}
.noSmoothing {
    image-rendering: optimizeSpeed;             // Older versions of FF
    image-rendering: -moz-crisp-edges;          // FF 6.0+
    image-rendering: -webkit-optimize-contrast; // Webkit
    image-rendering: -o-crisp-edges;            // OS X & Windows Opera (12.02+)
    image-rendering: optimize-contrast;         // Possible future browsers.
    -ms-interpolation-mode: nearest-neighbor;   // IE
}
h1 {font:24px sans-serif}
<h1>Canvas with no modifications</h1>
<canvas id="smoothing" width="300" height="150"></canvas>

<h1>Canvas with smoothing off</h1>
<canvas id="nosmoothing" width="300" height="150" class="noSmoothing"></canvas>
  • Thank you for your answer, please see updated version. I added 3rd image which is when I turn off canvas' anti-aliasing for images. – Vince Dec 26 '17 at 18:54