简体   繁体   English

在HTML画布上填充某些像素

[英]Filling in certain pixels on an HTML canvas

First off, sorry about the bad title, I couldn't think of a better way to describe what I was trying to do. 首先,抱歉糟糕的标题,我想不出更好的方式来描述我想要做的事情。 I have an HTML canvas, which, for argument's sake, is x pixels wide and y pixels tall. 我有一个HTML画布,为了论证的缘故,它是x像素宽, y像素高。 I have been trying to write a code that takes the location in the array of the canvas' image data of two pixels that are on lines z and z + 1 and fill in all the pixels in the higher row between the two pixels a certain color. 我一直在尝试编写一个代码,该代码获取画布的数组中位于zz + 1上的两个像素的图像数据中的位置,并填充两个像素之间的较高行中的所有像素的某种颜色。 I'm afraid I may not have made much sense, so here's a diagram: 我担心我可能没有多大意义,所以这是一个图表:

A pair of pixels http://i63.tinypic.com/2jg583k.png 一对像素http://i63.tinypic.com/2jg583k.png

Sorry about the poor graphics, but assume each rectangle is a pixel. 抱歉图形不佳,但假设每个矩形都是一个像素。 The program should take in the first value for each of the black pixels (each is stored as r,g,b,a, the program gets the location of the r in the array representing the canvas' image data), and stores the r value for the lower pixel as bottomPixel and the higher one as topPixel . 程序应该为每个黑色像素取第一个值(每个都存储为r,g,b,a,程序获取表示画布'图像数据的数组中r的位置),并存储r较低像素的值为bottomPixel ,较高的topPixel In this case, bottomPixel = 124 and topPixel = 112 It should use this to fill all pixels between the two base pixels a certain color. 在这种情况下, bottomPixel = 124topPixel = 112它应该使用它来填充两个基本像素之间的所有像素的某种颜色。 For example, using the previous pixel locations, the red pixels in the following picture should be colored in, but the blue one should not. 例如,使用先前的像素位置,下图中的红色像素应该着色,但蓝色像素不应该着色。

Colored canvas http://i66.tinypic.com/21blzq8.png 彩色帆布http://i66.tinypic.com/21blzq8.png

Here is the code I have: (Assume that the canvas has an Id "Canvas" and is 6px wide by 10px tall) 这是我的代码:(假设画布有一个Id“Canvas”,宽6px,高10px)

var cnvs        = document.getElementById("Canvas");
cnvs.height     = 10; //This height and width is here as an example.
cnvs.width      = 6;
var cont        = cnvs.getContext("2d");
var environment = cont.getImageData(0,0,6,10);
var bottomPixel = 124;//Not neccesarily 124 or 112, just example values
var topPixel    = 112;
if ( bottomPixel - topPixel > 6*4 ) //If bottomPixel is to the right of topPixel
{
   for ( var i = 0 ; i < ((bottomPixel-6*4)-topPixel)/4 ; i++ )
   {
      var index = topPixel + i * 4;
      environment.data[index]      = 0;
      environment.data[index + 1 ] = 255;
      environment.data[index + 2 ] = 0;
      environment.data[index + 3 ] = 255;
   }
}
if ( bottomPixel - topPixel > 6*4 ) //If bottomPixel is to the left of topPixel
{
   for ( var i = 0 ; i < (topPixel-(bottomPixel-6*4))/4; i++ )
   {
      var index = topPixel - i * 4;
      environment.data[index]      = 0;
      environment.data[index + 1 ] = 255;
      environment.data[index + 2 ] = 0;
      environment.data[index + 3 ] = 255;
   }
}

I'd like to know why my code isn't doing what I previously described. 我想知道为什么我的代码没有按照我之前的描述进行操作。 If anything here needs clarification, please leave a comment. 如果此处有任何需要澄清的话,请发表评论。 Thanks! 谢谢!

This is a method that works on the point coordinates and uses a the setPixel function to modify imageData. 这是一种适用于点坐标的方法,并使用setPixel函数来修改imageData。 I'm using blue for start and black for end. 我用蓝色开始,黑色用完。 You'll need to adjust for your exact condition but you can use setPixel to allow for direct x and y edits on the imageData. 您需要根据具体情况进行调整,但可以使用setPixel在imageData上进行直接的x和y编辑。

update 更新

I've included an alternate line method and your line method. 我已经包含了备用线方法和你的线方法。 There is also an animation that will help you find errors. 还有一个动画可以帮助您找到错误。

 function ptIndex(p, w) { return ((px|0) + ((py|0) * w)) * 4; } function setPixel(p, w, d, rgba) { var i = ptIndex(p, w); d[i] = rgba.r; d[i + 1] = rgba.g; d[i + 2] = rgba.b; d[i + 3] = rgba.a; } function yourLine(p1, p2, w, d, rgba) { var cnvs = document.getElementById("Canvas"); var bottomPixel = ptIndex(p1, w); var topPixel = ptIndex(p2, w) if (bottomPixel - topPixel > w * 4) //If bottomPixel is to the right of topPixel { for (var i = 0; i < ((bottomPixel - w * 4) - topPixel) / 4; i++) { var index = topPixel + i * 4; d[index] = rgba.r; d[index + 1] = rgba.g; d[index + 2] = rgba.b; d[index + 3] = rgba.a } } if (bottomPixel - topPixel > w * 4) //If bottomPixel is to the left of topPixel { for (var i = 0; i < (topPixel - (bottomPixel - w * 4)) / 4; i++) { var index = topPixel - i * 4; d[index] = rgba.r; d[index + 1] = rgba.g; d[index + 2] = rgba.b; d[index + 3] = rgba.a } } } function drawRandPoints() { var cnvs = document.getElementById("Canvas"); var cont = cnvs.getContext("2d"); // ghost last draw cont.fillStyle = "white"; cont.fillRect(0, 0, cnvs.width, cnvs.height); // get image data var environment = cont.getImageData(0, 0, cnvs.width, cnvs.height); var d = environment.data, w = cnvs.width; // create colors var black = { r: 0, g: 0, b: 0, a: 255 }; var red = { r: 255, g: 0, b: 0, a: 255 }; var blue = { r: 0, g: 0, b: 255, a: 255 }; var frames = 0; var p1 = {x: ((cnvs.width / 2|0)), y: 0, sx: 1, sy:0}; var p2 = {x: cnvs.width, y: ((cnvs.height / 2)|0), sx: -1, sy: 0}; function step(p) { if (px > cnvs.width) { px = cnvs.width; p.sx = 0; p.sy = 1; } if (py > cnvs.height) { py = cnvs.height; p.sy = 0; p.sx = -1; } if (px < 0) { px = 0; p.sx = 0; p.sy = -1; } if (py < 0) { py = 0; p.sy = 0; p.sx = 1; } } function ani() { cont.fillStyle = "white"; cont.fillRect(0, 0, cnvs.width, cnvs.height); environment = cont.getImageData(0, 0, cnvs.width, cnvs.height); d = environment.data; step(p1); step(p2); var p3 = { x: cnvs.width - p1.x, y: cnvs.height - p2.y }; var p4 = { x: cnvs.width - p2.x, y: cnvs.height - p1.y }; yourLine(p1, p2, w, d, {r:0,g:255,b:0,a:255}); myDrawLine(p1, p2, w, d, red); drawLineNoAliasing(p3, p4, w, d, blue); setPixel(p1, w, d, black); setPixel(p2, w, d, black); frames %= 12; p1.x += p1.sx; p1.y += p1.sy; p2.x += p2.sx; p2.y += p2.sy; // Put the pixel data on the canvas. cont.putImageData(environment, 0, 0); requestAnimationFrame(ani); } ani(); } function myDrawLine(p1, p2, w, d, rgba) { // Get the max length between x or y var lenX = Math.abs(p1.x - p2.x); var lenY = Math.abs(p1.y - p2.y); var len = Math.sqrt(Math.pow(lenX,2) + Math.pow(lenY,2)); // Calculate the step increment between points var stepX = lenX / len; var stepY = lenY / len; // If the first x or y is greater then make step negetive. if (p2.x < p1.x) stepX *= -1; if (p2.y < p1.y) stepY *= -1; // Start at the first point var x = p1.x; var y = p1.y; for (var i = 0; i < len; i++) { x += stepX; y += stepY; // Make a point from new x and y var p = { x: x, y: y }; // Draw pixel on data setPixel(p, w, d, rgba); // reached goal (removes extra pixel) if (Math.abs(px - p2.x) <= 1 && Math.abs(py - p2.y) <= 1) { break; } } // Draw start and end pixels. (might draw over line start and end) setPixel(p1, w, d, rgba); setPixel(p2, w, d, rgba); } // alternate from http://stackoverflow.com/questions/4261090/html5-canvas-and-anti-aliasing answer // 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(p1, p2, w, d, rgba) { var dist = DBP(p1.x, p1.y, p2.x, p2.y); // length of line var ang = getAngle(p2.x - p1.x, p2.y - p1.y); // angle of line var cos = Math.cos(ang); var sin = Math.sin(ang); for (var i = 0; i < dist; i++) { // for each point along the line var pt = { x: p1.x + cos * i, y: p1.y + sin * i }; setPixel(pt, w, d, rgba); } } // end alt drawRandPoints(); 
 #Canvas { border: 1px solid red image-rendering: optimizeSpeed; /* Older versions of FF */ image-rendering: -moz-crisp-edges; /* FF 6.0+ */ image-rendering: -webkit-optimize-contrast; /* Safari */ image-rendering: -o-crisp-edges; /* OS X & Windows Opera (12.02+) */ image-rendering: pixelated; /* Awesome future-browsers */ image-rendering: optimize-contrast; /* CSS3 Proposed */ -ms-interpolation-mode: nearest-neighbor; /* IE */ } 
 <canvas id="Canvas" width="128" height="64" style="width:320px"></canvas> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM