Category Archives: pixel manipulation

Interesting Texture #3

Actionscript:
  1. var canvas:BitmapData = new BitmapData(1500,1000,false, 0x000000);
  2. addChild(new Bitmap(canvas));
  3. scaleX = scaleY = .5;
  4.  
  5. var w:int = canvas.width;
  6. var w10:int = w * 80;
  7. var convert:Number = Math.PI/180;
  8. var size:int = canvas.width * canvas.height;
  9. for (var i:int = 0; i<size; i++){
  10.     var xp:int = i % w;
  11.     var yp:int = int(i / w);
  12.     var xp2:int = xp * 2;
  13.     var c1:int = (255/8) * (Math.cos(xp2 * convert) - Math.sin(yp*(xp2 + 500)/w10));
  14.     if (c1 <0) c1 = 256 - c1;
  15.     c1 = (c1 <<2 | c1) ;
  16.     canvas.setPixel(xp, yp, c1 <<15 | c1 <<9 | c1 );
  17. }
  18. var m:Matrix = new Matrix();
  19. m.scale(1,-1);
  20. m.translate(0,canvas.height);
  21. var clone:BitmapData = canvas.clone();
  22. canvas.draw(clone, m, null, BlendMode.SUBTRACT);
  23. clone.draw(canvas);
  24. clone.applyFilter(clone, clone.rect, new Point(0,0), new BlurFilter(10,10,1));
  25. canvas.draw(clone, null, null, BlendMode.ADD);
  26. var gray:ColorMatrixFilter = new ColorMatrixFilter([1, 0.55, 0.55, 0,0,0.55, 0.9, 0.55, 0,0,0.55, 0.55, 0.550,0, 0,0,0,1,0]);
  27. canvas.applyFilter(canvas, canvas.rect, new Point(0,0), gray);

Soon I'll work on a real-time variation. For now, here is one more still...

Also posted in BitmapData, setPixel | Tagged , , | Leave a comment

Interesting Texture #2

Actionscript:
  1. var canvas:BitmapData = new BitmapData(1000,1000,false, 0x000000);
  2. addChild(new Bitmap(canvas));
  3. scaleX = scaleY = .5;
  4.  
  5. var w:int = canvas.width;
  6. var w10:int = w * 40;
  7. var size:int = canvas.width * canvas.height;
  8. for (var i:int = 0; i<size; i++){
  9.     var xp:int = i % w;
  10.      
  11.     var yp:int = int(i / w);
  12.     var c1:int = (255/8) * (Math.cos(xp* Math.PI/180 * 2) + Math.sin(yp*(xp + 200)/w10));
  13.     if (c1 <0) c1 = 256 - c1;
  14.     c1 = (c1 <<1 | c1) ;
  15.     canvas.setPixel(xp, yp, c1 <<15 | c1 <<7 | c1 );
  16. }
  17. var m:Matrix = new Matrix();
  18. m.scale(1,-1);
  19. m.translate(0,canvas.height);
  20. var clone:BitmapData = canvas.clone();
  21. canvas.draw(clone, m, null, BlendMode.SUBTRACT);
  22. clone.draw(canvas);
  23. clone.applyFilter(clone, clone.rect, new Point(0,0), new BlurFilter(10,10,1));
  24. canvas.draw(clone, null, null, BlendMode.ADD);

Randomly bit shifting on this one is actually getting a good deal of millage.. I know I can easily optimize so that it works in realtime - could even be done in pixelbender... but going to play a bit more first before I optimize....

Also posted in BitmapData, misc, setPixel | Tagged , , | Leave a comment

Interesting Texture

Actionscript:
  1. var canvas:BitmapData = new BitmapData(1000,1000,false, 0x000000);
  2. addChild(new Bitmap(canvas));
  3. scaleX = scaleY = .5;
  4.  
  5. var w:int = canvas.width;
  6. var w10:int = w * 60;
  7. var size:int = canvas.width * canvas.height;
  8. for (var i:int = 0; i<size; i++){
  9.     var xp:int = i % w;
  10.      
  11.     var yp:int = int(i / w);
  12.     var c1:int = (255/8) * (Math.cos(xp* Math.PI/180 * 2) + Math.sin(yp*yp/w10));
  13.     if (c1 <0) c1 = 256 - c1;
  14.     c1 = (c1 <<1 | c1) ;
  15.     canvas.setPixel(xp, yp, c1 <<16 | c1 <<8 | c1 );
  16. }
  17. var m:Matrix = new Matrix();
  18. m.scale(1,-1);
  19. m.translate(0,canvas.height);
  20. var clone:BitmapData = canvas.clone();
  21. canvas.draw(clone, m, null, BlendMode.SUBTRACT);
  22. clone.draw(canvas);
  23. clone.applyFilter(clone, clone.rect, new Point(0,0), new BlurFilter(10,10,1));
  24. canvas.draw(clone, null, null, BlendMode.ADD);

Having one of those days where everything I code doesn't look right to me... took a little break from other work and created this very unoptimized abstract texture... no animation so here is a bitmap:

Also posted in BitmapData, setPixel | Tagged , , | Leave a comment

Perlin Outlines

Actionscript:
  1. [SWF(width = 600, height=600, backgroundColor=0xCCCCCC, frameRate=24)]
  2. var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight, false, 0x000000);
  3. var blur:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight, false, 0x000000);
  4. addChild(new Bitmap(canvas, "auto", true));
  5.  
  6. var w:int = canvas.width
  7. var hw:int = w / 2;
  8. var size:int = w * w;
  9. var seed:Number = Math.random()*100;
  10. var pnt:Point = new Point();
  11. var dy:Number = 0, dx:Number = 0;
  12. var blr:BlurFilter = new BlurFilter(10,10,1);
  13. addEventListener(Event.ENTER_FRAME, onLoop);
  14. function onLoop(evt:Event):void {
  15.    
  16.     dx += (mouseX - dx) / 4;
  17.     dy += (mouseY - dy) / 4;
  18.     canvas.lock();
  19.     canvas.perlinNoise(hw,hw,2,seed,false, false, 1, true, [new Point(dx, dy), new Point(-dx, -dy)]);
  20.     var pix:Vector.<uint> = canvas.getVector(canvas.rect);
  21.     for (var i:int = 0; i<size; i++){
  22.         var col:uint = 255 - pix[i] <<4 & 0x00FF00;
  23.         pix[i] = col <<8 | col | col>> 8;
  24.     }
  25.     canvas.setVector(canvas.rect, pix);
  26.     blur.copyPixels(canvas, canvas.rect, pnt);
  27.     blur.applyFilter(blur, blur.rect, pnt, blr);
  28.     canvas.draw(blur, null, null, BlendMode.DIFFERENCE);
  29.     canvas.draw(canvas, null, null, BlendMode.INVERT);
  30.     canvas.unlock();
  31. }

This is actually an optimized variation on some recent posts that made use of perlin noise. You can get a wide range of effects by changing just the BlendMode values alone.... I particularly like this combination of BlendModes because it reminds me a bit of a terrain map...

Have a look at the swf...

Also posted in BitmapData, Vector | Tagged , , | Leave a comment

Another Perlin Texture

Actionscript:
  1. var canvas:BitmapData = new BitmapData(1200,1200,false, 0x000000);
  2. addChild(new Bitmap(canvas));
  3.  
  4. scaleX = scaleY = 0.5;
  5. var w:int = canvas.width
  6. var hw:int = w / 2;
  7. var hhw:int = hw / 2;
  8. var size:int = canvas.width * canvas.width;
  9.  
  10. canvas.perlinNoise(hhw,hhw,1,Math.random()*100,false, false, 1, true);
  11.  
  12. for (var i:int = 0; i<size; i++){
  13.     var xp:int = i % w;
  14.     var yp:int = int(i / w);
  15.     var col:uint =  canvas.getPixel(xp, yp) / (-20|i+xp)>> 8 & 0xFF
  16.     canvas.setPixel(xp, yp, col <<16 | col <<8 | col);
  17. }
  18.  
  19. canvas.applyFilter(canvas, canvas.rect, new Point(0,0), new BlurFilter(4,4,1));
  20. var blur:BitmapData = canvas.clone();
  21. blur.applyFilter(blur, blur.rect, new Point(0,0), new BlurFilter(10,10,1));
  22.  
  23. canvas.draw(blur, null, null, BlendMode.DARKEN);

This is a variation on yesterdays post. I think it's time to optimize this and see how it does in real time...

Here is what this snippet will draw:

Also posted in BitmapData, misc, setPixel | Tagged , , | 2 Comments

drawTriangles() Terrain

Actionscript:
  1. [SWF(width=500,height=500,backgroundColor=0x333333, frameRate=40)]
  2. var terrain:Shape = Shape(addChild(new Shape()));
  3. terrain.x = terrain.y = 250;
  4. var rows:int = 60;
  5. var size:int = rows + 1;
  6. var vertNum:int = size * size;
  7. var polySize:Number = 5;
  8. var gridWidth:Number = polySize * rows;
  9. var halfWidth:Number = gridWidth / 2;
  10. var verts:Vector.<Number> = new Vector.<Number>();
  11. var pVerts:Vector.<Number> = new Vector.<Number>();
  12. var indices:Vector.<int> = new Vector.<int>();
  13. var uvs:Vector.<Number> = new Vector.<Number>();
  14. var uvts:Vector.<Number> = new Vector.<Number>();
  15. var tex:BitmapData = new BitmapData(gridWidth, gridWidth, false, 0x000000);
  16. var pix:int = gridWidth * gridWidth;
  17. var perlin:BitmapData = new BitmapData(gridWidth, gridWidth, false, 0x000000);
  18. // generate the texture and the terrain
  19. function generate():void{
  20.     tex.fillRect(tex.rect, 0x000000);
  21.     var i:Number, xp:Number, yp:Number;
  22.     for (i = 0; i<pix; i++){
  23.         xp = i % gridWidth;
  24.         yp= int(i / gridWidth);
  25.         var dx:Number = xp - gridWidth / 2;
  26.         var dy:Number = yp - gridWidth / 2;
  27.         var d:Number = 255 - Math.sqrt(dx * dx + dy * dy) / halfWidth* 255;
  28.         if (d <0) d = 0;
  29.         if (d> 255) d = 255;
  30.         var c:uint = uint(d);
  31.         tex.setPixel(xp, yp, c <<16 | c <<8 | c);
  32.     }
  33.     perlin.perlinNoise(100,100,3,Math.random()*100,false,false,7,true);
  34.     perlin.draw(perlin, null, null, BlendMode.SCREEN);
  35.     tex.draw(perlin, null, null, BlendMode.MULTIPLY);
  36.     // calculate verts, uvs and indices
  37.     var vIndex:int = 0;
  38.     var uvIndex:int = 0;
  39.     indices = new Vector.<int>();
  40.     for (i = 0; i<vertNum; i++){
  41.         var xMod:Number = i % size;
  42.         xp = xMod * polySize;
  43.         yp = int(i / size) * polySize;
  44.         verts[vIndex++] = xp - halfWidth;
  45.         verts[vIndex++] = yp - halfWidth;
  46.         verts[vIndex++] = tex.getPixel(xp, yp) & 0xFF;
  47.         uvs[uvIndex++] = xp /  gridWidth;
  48.         uvs[uvIndex++] = yp / gridWidth;
  49.         if (xMod != rows){
  50.               indices.push(i, i+1, i+size, i+1, i+size+1, i+size);
  51.         }
  52.     }
  53. }
  54. generate();
  55. stage.addEventListener(MouseEvent.MOUSE_DOWN, onGenerate);
  56. function onGenerate(evt:MouseEvent):void{ generate() };
  57. var m:Matrix3D = new Matrix3D();
  58. var rot:Number = 0;
  59. addEventListener(Event.ENTER_FRAME, onLoop);
  60. function onLoop(evt:Event):void {
  61.         m.identity();
  62.         var destRot:Number = mouseX / stage.stageWidth * 90;
  63.         if (destRot <0) destRot = 0;
  64.         if (destRot> 90) destRot = 90;
  65.         rot += (destRot - rot) * 0.2;
  66.         m.appendRotation(rot,Vector3D.Z_AXIS);
  67.         m.appendRotation(60,Vector3D.X_AXIS);
  68.         Utils3D.projectVectors(m, verts, pVerts, uvts);
  69.         with(terrain.graphics){
  70.             clear();
  71.             beginBitmapFill(tex, null, false, true);
  72.             drawTriangles(pVerts, indices, uvs, TriangleCulling.NEGATIVE);
  73.         }
  74. }

This snippet draws a pretty simple isometric terrain using fp10 graphics stuff and perlin noise.


Have a look at the swf here...

Also posted in BitmapData, Graphics, Vector, setPixel | Tagged , , | 4 Comments

setVector() CA Texture

Actionscript:
  1. [SWF(width=500, height=500)]
  2. var canvasSize:int=stage.stageWidth;
  3. var canvas:BitmapData=new BitmapData(canvasSize,canvasSize,false,0x000001);
  4. addChild(new Bitmap(canvas, "auto", true));
  5. var size:int=canvas.width*canvas.height - canvasSize;
  6. var pixels:Vector.<uint>=canvas.getVector(canvas.rect);
  7. for (var i:int = 0; i<canvasSize; i++) {
  8.     var xp:int=int(Math.random()*canvasSize);
  9.     var yp:int=int(Math.random()*canvasSize);
  10.     pixels[xp+yp*canvasSize]=0xFF000000;
  11. }
  12. var targetCol:uint=0xFF000000;
  13. var buffer:Vector.<uint>=pixels.concat();
  14. var fade:uint=1;
  15.  
  16. addEventListener(Event.ENTER_FRAME, onLoop);
  17. function onLoop(evt:Event):void {
  18.     var curr:uint=targetCol;
  19.     var r:int = (curr>> 16) & 0xFF;
  20.     var g:int = (curr>> 8) & 0xFF;
  21.     var b:int=curr&0xFF;
  22.     r+=fade;
  23.     g+=fade;
  24.     b+=fade;
  25.     if (r>255) r=255;
  26.     if (g>255) g=255;
  27.     if (b>255) b=255;
  28.     var darker:uint=0xFF000000|r<<16|g<<8|b;
  29.     if (darker==0xFFFFFFFF) {
  30.         removeEventListener(Event.ENTER_FRAME, onLoop);
  31.     }
  32.     for (var i:int = canvasSize; i<size; i++) {
  33.         curr=pixels[i];
  34.         if (curr==targetCol) {
  35.             var index:int=i-canvasSize+int(Math.random()*3) - 1;
  36.             if (index>0) buffer[index]=darker;
  37.             if (int(Math.random()*50)==1) {
  38.                 index=i-canvasSize+int(Math.random()*3)-1;
  39.                 if (index>0) buffer[index]=darker;
  40.             }
  41.         }
  42.     }
  43.     targetCol=darker;
  44.     canvas.lock();
  45.     canvas.setVector(canvas.rect, buffer);
  46.     pixels=buffer.concat();
  47.     canvas.unlock();
  48. }

This snippet uses setVector() to draw something that looks like this:

This is a cellular automaton. It has kind of a strange rule set - but you could easily use this snippet to do more traditional cellular automata.

Also posted in BitmapData, Vector | Tagged , , | Leave a comment

Bresenham’s Circle and setVector()

Actionscript:
  1. var canvasSize:int = 400;
  2. var canvas:BitmapData = new BitmapData(canvasSize, canvasSize, false, 0xFFFFFF);
  3. addChild(new Bitmap(canvas));
  4. var size:int = canvas.width * canvas.height;
  5. var pixels:Vector.<uint> = canvas.getVector(canvas.rect);
  6.  
  7. addEventListener(Event.ENTER_FRAME, onLoop);
  8. function onLoop(evt:Event):void {
  9.      for (var i:int = 0; i<500; i++){
  10.       fillCircle(int(Math.random() * canvasSize),
  11.                       int(Math.random() * canvasSize),
  12.                       int(Math.random() * 5 + 3),
  13.                       uint(Math.random() * 0xFFFF));
  14.      }
  15.      canvas.lock();
  16.      canvas.setVector(canvas.rect, pixels);
  17.      canvas.unlock();
  18. }
  19.  
  20. function fillCircle(xp:int,yp:int, radius:int, col:uint = 0x000000):void {
  21.     var xoff:int =0;
  22.     var yoff:int = radius;
  23.     var balance:int = -radius;
  24.     while (xoff <= yoff) {
  25.          var p0:int = xp - xoff;
  26.          var p1:int = xp - yoff;
  27.          var w0:int = xoff + xoff;
  28.          var w1:int = yoff + yoff;
  29.          hLine(p0, yp + yoff, w0, col);
  30.          hLine(p0, yp - yoff, w0, col);
  31.          hLine(p1, yp + xoff, w1, col);
  32.          hLine(p1, yp - xoff, w1, col);
  33.         if ((balance += xoff++ + xoff)>= 0) {
  34.             balance-=--yoff+yoff;
  35.         }
  36.     }
  37. }
  38. function hLine(xp:int, yp:int, w:int, col:uint):void {
  39.     var index:int = xp + yp * canvasSize;
  40.     for (var i:int = 0; i <w; i++){
  41.         index++;
  42.         if (index> -1 && index <size){
  43.           pixels[index] = col;
  44.         }
  45.     }
  46. }

In the past I've posted examples of Bresenham's Circle (here and here). Both of those examples make use of setPixel(). Today's snippet demos a version of Bresenham's Circle that works with setVector().

Also posted in BitmapData, graphics algorithms, setPixel | Tagged , , , | Leave a comment

x and y Coordinates in 1D Array / Vector

Actionscript:
  1. var canvas:BitmapData=new BitmapData(400,400,false,0x000000);
  2. addChild(new Bitmap(canvas));
  3. var pix:Vector.<uint>=canvas.getVector(canvas.rect);
  4.  
  5. canvas.lock();
  6. for (var i:int = 0; i<300; i++) {
  7.     var xp:int=50+i;
  8.     var yp:int=50+i/2;
  9.     // target x and y coords in 1D array
  10.     pix[xp+yp*400]=0xFFFFFF;
  11. }
  12. canvas.setVector(canvas.rect, pix);
  13. canvas.unlock();

This snippet shows how to target x and y coordinates in a 1D Array / Vector. This can be useful sometimes when working with setVector().

This is sort of like re-inventing setPixel().... and for that reason is kind of pointless - that said, it's interesting to know. I first learned about this technique from using processing.

Also posted in BitmapData, Vector, arrays, setPixel | Tagged , , | Leave a comment

sine cosine Gradient

Actionscript:
  1. [SWF(width=600,height=500,frameRate=30)]
  2. var canvas:BitmapData=new BitmapData(600,500,false,0x000000);
  3. addChild(new Bitmap(canvas));
  4. var size:Number=canvas.width*canvas.height;
  5. var w:Number=canvas.width;
  6. var wd:Number=1/w;
  7. var pix:Vector.<uint> = new Vector.<uint>();
  8. var sin:Number;
  9. var cos:Number;
  10. var dx:Number=110;
  11. var dy:Number=52;
  12. addEventListener(Event.ENTER_FRAME, onLoop);
  13. function onLoop(evt:Event):void {
  14.     dx+=0.001;
  15.     canvas.lock();
  16.     for (var i:int = 0; i<size; i++) {
  17.         var xp:Number=i%w;
  18.         var yp:Number=int(i*wd);
  19.         var xx:Number=xp*0.05+dx;
  20.         var yy:Number=yp*0.05+dy;
  21.         var t:Number= (xx * yy) % 3.14159265;
  22.         //compute sine
  23.         // technique from http://lab.polygonal.de/2007/07/18/fast-and-accurate-sinecosine-approximation/
  24.         // by Michael Baczynski
  25.         if (t<0) {
  26.             sin=1.27323954*t+.405284735*t*t;
  27.         } else {
  28.             sin=1.27323954*t-0.405284735*t*t;
  29.         }
  30.         //compute cosine: sin(t + PI/2) = cos(t)
  31.         t+=1.57079632;
  32.         if (t>3.14159265) {
  33.             t-=6.28318531;
  34.         }
  35.         if (t<0) {
  36.             cos=1.27323954*t+0.405284735*t*t;
  37.         } else {
  38.             cos=1.27323954*t-0.405284735*t*t;
  39.         }
  40.         var c:Number=sin+cos*cos*cos;
  41.         // fast math abs
  42.         c=c<0? -c:c;
  43.         c=c*140;
  44.         // math max 255
  45.         c=c>255?255:c;
  46.         pix[i]=c<<16|c<<8|c;
  47.     }
  48.     canvas.setVector(canvas.rect, pix);
  49.     canvas.unlock();
  50. }

The above snippet will animate a gradient that looks like this:

Also posted in BitmapData, Vector, graphics algorithms | 3 Comments