2010-11-23 2 views
42

Как включить сглаживание на холст.HTML5 Холст и сглаживание

Следующий код не рисует плавную линию:

var context = mainCanv.getContext("2d"); 
if (context) { 
    context.moveTo(0,0); 
    context.lineTo(100,75); 

    context.strokeStyle = "#df4b26"; 
    context.lineWidth = 3; 
    context.stroke(); 
} 
+3

Согласно [этому StackOverflow вопрос] (http://stackoverflow.com/questions/195262/can -i-turn-off-antialiasing-on-an-html-canvas-element) казалось бы, что canvas * * сглаживается по умолчанию. Какую ОС/браузер/версию вы используете? – Phrogz 2010-11-23 21:26:57

+2

Когда вы говорите, что это негладко, что вы имеете в виду? Вы видите зубчатые края/пиксели или просто размыты? – 2011-03-08 10:18:30

+0

Это происходит на Firefox Mobile на Android, на красной линии есть уродливая серая рамка. – 2014-03-24 10:06:19

ответ

16

мне не нужно, чтобы включить анти-псевдоним, потому что это по умолчанию, но я нуждался, чтобы выключить его. И если его можно отключить, он также может быть включен.

ctx.imageSmoothingEnabled = true; 

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

5

Вот обходное решение, которое требует от вас рисования линий по пикселям, но предотвратит сглаживание.

// 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<dist;i++) { 
     // for each point along the line 
     ctx.fillRect(Math.round(sx + Math.cos(ang)*i), // round for perfect pixels 
        Math.round(sy + Math.sin(ang)*i), // thus no aliasing 
        1,1); // fill in one pixel, 1x1 
    } 
} 

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

Вызов его с

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

Вы можете перевести холст на расстоянии половины пикселей.

ctx.translate(0.5, 0.5); 

Первоначально точка позиционирования холста между физическими пикселями.

1

Если вам нужен контроль над уровнем содержимого на уровне пикселей, вы можете использовать createImageData и putImageData.

HTML:

<canvas id="qrCode" width="200", height="200"> 
    QR Code 
</canvas> 

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

Working sample here

Смежные вопросы