drawImage () создать размытое изображение - PullRequest
0 голосов
/ 26 сентября 2018

Мне жаль задавать этот вопрос, который был опубликован несколько раз, но другие отзывы о размытых изображениях не помогают мне решить проблему размытия.

Так что я могу увеличивать / уменьшать масштаб на холстес помощью прокрутки с помощью drawImage ().В моем проекте я использую PIXI, но у меня та же проблема.

Я заметил, что при рисовании изображения вместо холста в drawImage () меньше размытия.Я должен использовать холст, потому что я хотел бы добавить к нему графику.

result drawImage () с изображением

result drawImage () с canvas

Вот демо: https://jsfiddle.net/wyllisMonteiro/0dvfe1a3/

Код:

var image = new Image();
var canvas = document.createElement( "canvas" );
var src = "https://www.maisons-elytis-lyonouest.fr/wp-content/uploads/Maison-M.-ST-GENIS-LES-OLLIERES-HD-3.jpg";
var isZoomIn = false;

$( document ).ready( function() {

    // load image
    image.addEventListener( "load", function() {

    // create canvas which store image
        canvas.setAttribute( "id", "test" );
        canvas.width = $( window ).width()-5;
        canvas.height = $( window ).height()-5;

        var context = canvas.getContext( "2d" );
        context.imageSmoothingEnabled       = true;
        context.mozImageSmoothingEnabled    = true;
        context.webkitImageSmoothingEnabled = true;

        context.clearRect( 0, 0, canvas.width, canvas.height );
        context.drawImage( image, 0, 0, canvas.width * 1, canvas.height * 1 );

        document.body.append( canvas );

        // Not usefull for the issue
        $( "#test" ).on( "click", function() {
            var ctx = canvas.getContext( "2d" );
            ctx.fillStyle = "green";
            ctx.fillRect(10, 10, 100, 100);
        } );
    } )
    image.src = src;

    document.addEventListener( 'mousewheel', zoomIn );
    document.addEventListener( 'DOMMouseScroll', zoomIn )

    function zoomIn( e ) {
    // define up or down scroll
        var e = window.event || e; // old IE support
        var canvasCtx = e.target.getContext( "2d" );
        var delta = Math.max( -1, Math.min( 1, ( e.wheelDelta || -e.detail ) ) );

        if( delta == 1 ) {
            if( !isZoomIn ) {
               $( "#test" )[0].getContext( "2d" ).drawImage( $( "#test" )[0], -canvas.width / 2, -300, canvas.width * 2, canvas.height * 2 );
               isZoomIn = true;
            }
        } else {
        isZoomIn = false;
            $( "#test" )[0].getContext( "2d" ).drawImage( image, 0, 0, canvas.width * 1, canvas.height * 1 );
        }
    }

} )

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

То, что вы заметили, очень просто объяснить:

Когда вы рисуете с холста, вы фактически изменяете размер уменьшенной версии исходного изображения, где пиксели были удалены.Хотя при рисовании исходного изображения все пиксели все еще доступны для увеличения.

Очевидно, что при использовании ухудшенной версии, которая в настоящее время нарисована на холсте, вы увидите больше артефактов.

Чтобы обойти это, вы можете сохранить копию своего холста с нарисованным на нем полным качеством вашего изображения и выполнять операции рисования на этом высококачественном холсте.
Затем вы сможетенарисуйте этот высококачественный холст обратно на видимом холсте при любом уровне масштабирования.

var out = output.getContext('2d'); // the canvas we will see
// create an 'offscreen' canvas
// it will store our high quality scene
var offscreen = document.createElement('canvas');
var off = offscreen.getContext('2d');

// 'img' won't get used anymore out of 'begin'
var img = new Image();
img.onload = begin;
img.src = "https://www.maisons-elytis-lyonouest.fr/wp-content/uploads/Maison-M.-ST-GENIS-LES-OLLIERES-HD-3.jpg";

var zoomed = false;
var mousedown = false;
var rad = 20;
var grad = off.createRadialGradient(rad/2, rad/2, rad, rad/2, rad/2, 0);
grad.addColorStop(0.2, 'transparent');
grad.addColorStop(1, 'gold');

function begin() {
  // first draw at full quality
  offscreen.width = img.width;
  offscreen.height = img.height;
  off.drawImage(img, 0, 0);
  off.fillStyle = grad;
  off.globalCompositeOperation = 'lighter';
  // then draw to the visible canvas
  drawToMain();
}
function drawToMain() {
  // draw our full quality canvas on the distorted, visible one
  if(zoomed) {
    // uniform scale + translate
    out.setTransform(2,0,0,2,-output.width/2, -output.height/2);
  }
  else {
    out.setTransform(1,0,0,1,0,0);
  }
  out.drawImage(offscreen, 0, 0, output.width, output.height);
}

function drawDot(x, y) {
  // we will draw on the offscreen canvas
  // so we need to convert the visible canvas coordinates
  // to the ones of our normal sized 'offscreen' canvas
  var ratio_x = offscreen.width / output.width;
  var ratio_y = offscreen.height / output.height;
  if(zoomed) {
    // apply the camera transforms
    // and non uniform scale (output distortion)
    off.setTransform(ratio_x / 2, 0,0,ratio_y / 2,0,0);
    x += (output.width / 2);
    y += (output.height / 2);
  }
  else {
    // simply distort our offscreen context by setting its scale factor
    off.setTransform(ratio_x, 0, 0, ratio_y, 0, 0);
  }
  // draw a dot.
  // Note that for such a drawing, you'd be better even redraw from scratch every time
  // instead of keeping an offscreen canvas
  // but for demo purposes...
  off.beginPath();
  off.arc(x, y, (rad * (+zoomed + 1)), 0, Math.PI*2);
  off.translate(x - rad /2, y - rad / 2);
  off.fill();
  // render our offscreen canvas on the visible one
  drawToMain();
}

check.onchange = function toggleZoom() {
  zoomed = !zoomed;
  drawToMain();
};

output.onmousemove = function mousemovehandler(evt) {
  if(mousedown) {
    var rect = output.getBoundingClientRect();
    drawDot(evt.clientX - rect.left, evt.clientY - rect.top);
  }
};
output.onmousedown = function mousedownhandler(evt) {
  mousedown = true;
  output.onmousemove(evt);
};
output.onmouseup = function() {
  mousedown = false;
}
<label>zoom<input type="checkbox" id="check"></label><br>
click and drag to draw dots on the canvas<br>
<canvas id="output" width="500" height="500"></canvas>
0 голосов
/ 26 сентября 2018

Здесь я удалил большую часть вашего кода, чтобы сделать его очень простым

var src = "https://www.maisons-elytis-lyonouest.fr/wp-content/uploads/Maison-M.-ST-GENIS-LES-OLLIERES-HD-3.jpg";
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

var image = new Image();
image.addEventListener("load", function() {  
  context.imageSmoothingEnabled = true;
  context.mozImageSmoothingEnabled = true;
  context.webkitImageSmoothingEnabled = true;
  context.drawImage(image, 0, 0, canvas.width, canvas.height);
});
image.src = src;

document.addEventListener('DOMMouseScroll', zoomIn);
document.addEventListener('mousewheel', zoomIn)


function zoomIn(e) {
  var z = 1
  context.drawImage(image, -1620/z, -1540/z, image.width/z, image.height/z);
}
<canvas id="canvas" height="600" width="900"></canvas>

Нет размытия, насколько я вижу ...
Вы можете попробовать изменить z = 1 на что-то немного выше, например 1,5, чтобы увидетьдругое увеличение.
Единственное, что я делаю по-другому, это увеличение ширины и высоты изображения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...