Lienzo HTML5 y Anti-aliasing

Cómo activar el suavizado en un canvas .

El siguiente código no dibuja una línea suave:

var context = mainCanv.getContext("2d"); if (context) { context.moveTo(0,0); context.lineTo(100,75); context.strokeStyle = "#df4b26"; context.lineWidth = 3; context.stroke(); } 

Anti-aliasing no se puede activar ni desactivar, y es controlado por el navegador.

¿Puedo desactivar el antialiasing en un elemento HTML ?

Puede traducir canvas por distancia de medio píxel.

 ctx.translate(0.5, 0.5); 

Inicialmente el punto de posicionamiento del canvas entre los píxeles físicos.

No he necesitado encender el anti-alias porque está activado por defecto pero he tenido que apagarlo. Y si se puede apagar, también se puede encender.

 ctx.imageSmoothingEnabled = true; 

Normalmente lo cierro cuando estoy trabajando en mi RPG de canvas, así que cuando hago zoom las imágenes no se ven borrosas.

Aquí hay una solución alternativa que requiere que dibuje líneas píxel por píxel, pero evitará el anti aliasing.

 // some helper functions // finds the distance between points function DBP(x1,y1,x2,y2) { return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); } // finds the angle of (x,y) on a plane from the origin function getAngle(x,y) { return Math.atan(y/(x==0?0.01:x))+(x<0?Math.PI:0); } // the function function drawLineNoAliasing(ctx, sx, sy, tx, ty) { var dist = DBP(sx,sy,tx,ty); // length of line var ang = getAngle(tx-sx,ty-sy); // angle of line for(var i=0;i 

Básicamente, usted encuentra la longitud de la línea y recorre paso por paso esa línea, redondeando cada posición y completando un píxel.

Llámalo con

 var context = cv.getContext("2d"); drawLineNoAliasing(context, 20,30,20,50); // line from (20,30) to (20,50) 

Si necesita control de nivel de píxel sobre canvas, puede hacerlo utilizando createImageData y putImageData .

HTML:

  QR Code  

Y JavaScript:

 function setPixel(imageData, pixelData) { var index = (pixelData.x + pixelData.y * imageData.width) * 4; imageData.data[index+0] = pixelData.r; imageData.data[index+1] = pixelData.g; imageData.data[index+2] = pixelData.b; imageData.data[index+3] = pixelData.a; } element = document.getElementById("qrCode"); c = element.getContext("2d"); pixcelSize = 4; width = element.width; height = element.height; imageData = c.createImageData(width, height); for (i = 0; i < 1000; i++) { x = Math.random() * width / pixcelSize | 0; // |0 to Int32 y = Math.random() * height / pixcelSize| 0; for(j=0;j < pixcelSize; j++){ for(k=0;k < pixcelSize; k++){ setPixel( imageData, { x: x * pixcelSize + j, y: y * pixcelSize + k, r: 0 | 0, g: 0 | 0, b: 0 * 256 | 0, a: 255 // 255 opaque }); } } } c.putImageData(imageData, 0, 0); 

Muestra de trabajo aquí

Ahora es 2018, y finalmente tenemos formas baratas de hacer algo al respecto …

De hecho, dado que la API de segundo contexto ahora tiene una propiedad de filter , y que esta propiedad de filtro puede aceptar SVGFilters , podemos construir un SVGFilter que mantendrá solo píxeles totalmente opacos de nuestros dibujos, y así eliminará el anti-aliasing predeterminado.

Por lo tanto, no desactivará el antialiasing per se, pero proporciona una forma económica tanto en términos de implementación como de rendimiento para eliminar todos los píxeles semitransparentes al dibujar.

No soy realmente un especialista de SVGFilters, por lo que podría haber una mejor manera de hacerlo, pero para el ejemplo, nodo para capturar solo píxeles totalmente opacos.

 var ctx = canvas.getContext('2d'); ctx.fillStyle = '#ABEDBE'; ctx.fillRect(0,0,canvas.width,canvas.height); ctx.fillStyle = 'black'; ctx.font = '14px sans-serif'; ctx.textAlign = 'center'; // first without filter ctx.fillText('no filter', 60, 20); drawArc(); drawTriangle(); // then with filter ctx.setTransform(1, 0, 0, 1, 120, 0); ctx.filter = 'url(#remove-alpha)'; // and do the same ops ctx.fillText('no alpha', 60, 20); drawArc(); drawTriangle(); // to remove the filter ctx.filter = 'none'; function drawArc() { ctx.beginPath(); ctx.arc(60, 80, 50, 0, Math.PI * 2); ctx.stroke(); } function drawTriangle() { ctx.beginPath(); ctx.moveTo(60, 150); ctx.lineTo(110, 230); ctx.lineTo(10, 230); ctx.closePath(); ctx.stroke(); } // unrelated // simply to show a zoomed-in version var zCtx = zoomed.getContext('2d'); zCtx.imageSmoothingEnabled = false; canvas.onmousemove = function drawToZoommed(e) { var x = e.pageX - this.offsetLeft, y = e.pageY - this.offsetTop, w = this.width, h = this.height; zCtx.clearRect(0,0,w,h); zCtx.drawImage(this, xw/6,yh/6,w, h, 0,0,w*3, h*3); } 
            
    Intereting Posts