Canvas HTML5 e anti-aliasing

Come triggersre l’ anti-alias su una canvas .

Il seguente codice non traccia una linea smussata:

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

L’anti-aliasing non può essere triggersto o distriggersto ed è controllato dal browser.

Posso distriggersre l’antialias su un elemento HTML?

Puoi tradurre la canvas con una distanza di mezzo pixel.

 ctx.translate(0.5, 0.5); 

Inizialmente il punto di posizionamento della canvas tra i pixel fisici.

Non ho bisogno di triggersre l’anti-alias perché è attivo per impostazione predefinita, ma ho dovuto distriggersrlo. E se può essere spento, può anche essere acceso.

 ctx.imageSmoothingEnabled = true; 

Di solito lo spengo quando lavoro sul mio rpg su canvas, quindi quando zoomo le immagini non sembrano sfocate.

Ecco una soluzione che richiede di disegnare linee pixel per pixel, ma impedirà l’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 

Fondamentalmente, trovi la lunghezza della linea, e passo dopo passo attraversa quella linea, arrotondando ogni posizione e riempiendo un pixel.

Chiamalo con

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

Se hai bisogno del controllo a livello di pixel sulla canvas, puoi utilizzare createImageData e putImageData .

HTML:

  QR Code  

E 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); 

Campione di lavoro qui

Siamo al 2018 e finalmente abbiamo modi economici per fare qualcosa intorno …

Infatti, poiché l’API di contesto 2d ora ha una proprietà filter e questa proprietà del filtro può accettare SVGFilters , possiamo creare un SVGFilter che manterrà solo i pixel completamente opachi dai nostri disegni e quindi eliminerà l’anti-alias predefinito.

Quindi non distriggers l’antialiasing di per sé, ma fornisce un modo economico sia in termini di implementazione che di performance per rimuovere tutti i pixel semitrasparenti durante il disegno.

Non sono uno specialista di SVGFilters, quindi potrebbe esserci un modo migliore per farlo, ma per l’esempio, userò un nodo per afferrare solo pixel completamente opachi.

 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); }