很抱歉问这个问题,这个问题已经发布了好几次了,但是其他有关模糊图像的回答并不能帮助我解决模糊问题。
因此,我可以使用drawImage()滚动放大/缩小画布。 在我的项目中,我使用PIXI,但是遇到了同样的问题。
我注意到,在drawImage()中放置图像而不是画布会减少模糊。我应该使用画布,因为我想在上面添加图形。
使用图像生成drawImage()
使用画布生成drawImage()
这里是演示: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 );
}
}
} )
答案 0 :(得分:0)
在这里,我删除了很多代码,以使其保持超级简单
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),以查看不同的缩放比例。
我要做的唯一不同就是缩放图像的宽度和高度
答案 1 :(得分:0)
您注意到的内容很容易解释:
从画布上绘制时,实际上是在调整原始图像的缩小版本的大小,该像素已被删除。当您绘制原始图像时,所有像素仍然可以执行放大操作。
因此,显然,使用当前在画布上绘制的降级版本时,您会看到更多的伪像。
要避免这种情况,您可以保留画布的副本,并在其上画上完整的图像质量,然后在此高质量的画布上进行绘制操作。
然后,您就可以在任何缩放级别上,在可见的画布上重新绘制此优质画布。
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>