我有这个用于缩放图像的代码。要zoomIn和zoomOut,请使用代码scalePicture(1.10, drawingContext);
和scalePicture(0.90, drawingContext);
。我在离屏画布上执行该操作,然后将图像复制回原始屏幕。
我使用了屏幕外处理,因为浏览器通过使用双缓冲来优化图像操作。我仍然有一个问题,当我放大约400%然后zoomOut回到原始大小时,图像质量显着下降。
我不依赖于原始图像,因为用户可以执行许多操作,例如剪辑,裁剪,旋转,注释,我需要在原始图像上堆叠所有操作。
任何人都可以提出一些建议/建议,以保持图像质量,同时不牺牲性能和质量。
scalePicture : function(scalePercent, operatingCanvasContext) {
var w = operatingCanvasContext.canvas.width,
h = operatingCanvasContext.canvas.height,
sw = w * scalePercent,
sh = h * scalePercent,
operatingCanvas = operatingCanvasContext.canvas;
var canvasPic = new Image();
operatingCanvasContext.save();
canvasPic.src = operatingCanvas.toDataURL();
operatingCanvasContext.clearRect (0,0, operatingCanvas.width, operatingCanvas.height);
operatingCanvasContext.translate(operatingCanvas.width/2, operatingCanvas.height/2);
canvasPic.onload = function () {
operatingCanvasContext.drawImage(canvasPic, -sw/2 , -sh/2 , sw, sh);
operatingCanvasContext.translate(-operatingCanvas.width/2, -operatingCanvas.height/2);
operatingCanvasContext.restore();
};
}
答案 0 :(得分:2)
画布是平局而忘记。如果不参考原始来源,就无法保留原始质量。
我建议重建记录的堆栈,但使用变换矩阵进行比例,旋转等的变化。然后将累积的矩阵应用于原始图像。这将保持最佳质量并提供一些性能提升(因为您只绘制最后和当前状态)。
类似于剪裁,计算和合并剪辑区域使用相同的矩阵,并在最终步骤中绘制原始图像之前应用剪辑。和文字等类似。
显示执行所有这些步骤的示例有点过于宽泛,但这里是一个示例,说明如何在原始图像上使用累积矩阵变换以保持最佳质量。您可以看到可以放大和缩小,旋转,每个实例中的图像都会以最佳质量渲染。
var ctx = c.getContext("2d"), img = new Image; // these lines just for demo init.
img.onload = demo;
ctx.fillText("Loading image...", 20, 20);
ctx.globalCompositeOperation = "copy";
img.src = "http://i.imgur.com/sPrSId0.jpg";
function demo() {
render();
zin.onclick = zoomIn; // accumulates transform, but render
zout.onclick = zoomOut; // based on original image using.
zrot.onclick = rotate; // current transformation matrix
}
function render() {ctx.drawImage(img, 0, 0)} // render original image
function zoomIn() {
ctx.translate(c.width * 0.5, c.height * 0.5); // pivot = center
ctx.scale(1.05, 1.05);
ctx.translate(-c.width * 0.5, -c.height * 0.5);
render();
}
function zoomOut() {
ctx.translate(c.width * 0.5, c.height * 0.5);
ctx.scale(1/1.05, 1/1.05);
ctx.translate(-c.width * 0.5, -c.height * 0.5);
render();
}
function rotate() {
ctx.translate(c.width * 0.5, c.height * 0.5);
ctx.rotate(0.3);
ctx.translate(-c.width * 0.5, -c.height * 0.5);
render();
}
<button id=zin>Zoom in</button>
<button id=zout>Zoom out</button>
<button id=zrot>Rotate</button><br>
<canvas id=c width=640 height=378></canvas>