Category Archives: pixel manipulation

Seamless Tiles

Actionscript:
  1. [SWF(width=600, height=500, backgroundColor=0xFFFFFF, frameRate=30)]
  2.  
  3. function seamlessTile(img:BitmapData, featherSize:Number = 5):BitmapData{
  4.     var pnt:Point = new Point(0,0);
  5.     var tile:BitmapData = new BitmapData(img.width, img.height, true, 0xFF000000);
  6.     tile.copyPixels(img, img.rect, pnt, null, null, true);
  7.    
  8.     var flipped:BitmapData = new BitmapData(img.width, img.height, true, 0xFF000000);
  9.     var m:Matrix = new Matrix();
  10.     m.scale(-1, 1);
  11.     m.translate(tile.width,0);
  12.     flipped.draw(tile, m);
  13.    
  14.     var aChannel:BitmapData = new BitmapData(img.width, img.height, true, 0x00000000);
  15.     var grad:Sprite = new Sprite();
  16.     m.createGradientBox(img.width, img.height, 0, 0, 0);
  17.    
  18.     grad.graphics.beginGradientFill(GradientType.LINEAR, [0xFFFFFF, 0xFFFFFF],  [1, 0], [0, (255 / img.width) * img.width / featherSize], m, SpreadMethod.PAD);
  19.    
  20.     grad.graphics.drawRect(0,0,img.width, img.height);
  21.     aChannel.draw(grad);
  22.  
  23.     tile.copyPixels(flipped, flipped.rect, pnt, aChannel, pnt, true);
  24.    
  25.     m.identity();
  26.     m.scale(1, -1);
  27.     m.translate(0,tile.height);
  28.     flipped.draw(tile, m)
  29.    
  30.     aChannel.fillRect(aChannel.rect, 0x00000000);
  31.     m.createGradientBox(img.width, img.height, Math.PI / 2, 0, 0);
  32.     grad.graphics.clear();
  33.     grad.graphics.beginGradientFill(GradientType.LINEAR, [0xFFFFFF, 0xFFFFFF], [1, 0], [0, (255 / img.height) * img.height / featherSize],  m, SpreadMethod.PAD);
  34.    
  35.     grad.graphics.drawRect(0,0,img.width, img.height);
  36.     aChannel.draw(grad, grad.transform.matrix);
  37.    
  38.     tile.copyPixels(flipped, flipped.rect, pnt, aChannel, pnt, true);
  39.     return tile;
  40. }
  41.  
  42. // test out the function:
  43. var canvas:BitmapData = new BitmapData(600, 470, true, 0xFF000000);
  44. addChild(new Bitmap(canvas));
  45.  
  46. var image:Loader = new Loader();
  47. image.load(new URLRequest("http://actionsnippet.com/imgs/paper.jpg"));
  48. image.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
  49. var texture:BitmapData;
  50.  
  51. function onLoaded(evt:Event):void {
  52.     texture =  Bitmap(image.content).bitmapData;
  53.     addEventListener(Event.ENTER_FRAME, onLoop);
  54.     image.removeEventListener(Event.COMPLETE, onLoaded);
  55. }
  56.  
  57. function onLoop(evt:Event):void{
  58.     var tile:BitmapData = seamlessTile(texture, Math.max(1,mouseX/30));
  59.     var p:Point = new Point();
  60.     for (var i:int = 0; i<8; i++){
  61.         p.x = (i % 4) * tile.width;
  62.         p.y = int(i / 4) * tile.height;
  63.         canvas.copyPixels(tile, tile.rect, p);
  64.     }
  65. }

The above demos a function called seamlessTile() which takes a BitmapData object and uses an oldschool seamless tile technique on it.

The result is that you can have an image that would normally tile like this:


end up looking like this:



You can take a look at the swf here.

I learned how seamless tiles worked by observing the KPT seamless welder filter while I was in highschool. I wish I could dig up all that old KPT stuff again....

There are better seamless tile algorithms out there.... this one is very primitive, but it will work nicely if used properly. Could work well with a composite texture in Papervision 3D for instance...

Also posted in BitmapData, graphics algorithms | Tagged , | 5 Comments

Game of Life Snippets

SNIPPET ONE

SNIPPET TWO

I was very impressed when I saw Mario Klingemann's game of line in 3 lines of code blog post late last year. I've been meaning to post about it for awhile - finally got around to it.

Mario Klingemann is the developer of Peacock... an excellent node based image generator written in ActionScript.

BitmapData.paletteMap() is very powerful. I haven't done much with it, but I have some ideas floating around.

For those of you that are game of live savvy... try other rule sets from the lexicon... my personal favorite has always been coral (45678/3). Here's a link to some more.

Another short game of life recently appeared on on the 25lines.com forums.... here... the forum post features a nice explanation for using a ConvolutionFilter and Threshold to create The Game of Life. The technique is so small and impressive looking that I figured I'd post it as is right here:

Actionscript:
  1. addChild(new Bitmap(new BitmapData(stage.stageWidth, stage.stageHeight, false, 0)))["bitmapData"].noise(int(Math.random()*int.MAX_VALUE),0,255,7,true);
  2. addEventListener(Event.ENTER_FRAME, function (e) {
  3.    getChildAt(0)["bitmapData"].applyFilter(getChildAt(0)["bitmapData"], getChildAt(0)["bitmapData"].rect, new Point(), new ConvolutionFilter(3, 3, [3,3,3,3,2,3,3,3,3],255,0,true,false,0,1));
  4.    getChildAt(0)["bitmapData"].threshold(getChildAt(0)["bitmapData"], getChildAt(0)["bitmapData"].rect, new Point(), "==", 8, 0xFFFFFFFF, 0xFC);
  5.    getChildAt(0)["bitmapData"].threshold(getChildAt(0)["bitmapData"], getChildAt(0)["bitmapData"].rect, new Point(), "!=", 0xFFFFFFFF, 0x00000000)})

The above code is by Daniil Tutubalin 25lines.com forums.

UPDATE:

Since writing this post the 25lines.com forum thread has grown to include a 4 line version and some additional discussion about this topic... be sure to check it out.

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

BitmapData lock() & unlock()

Actionscript:
  1. var size:Number = 400;
  2. var pixelNum:Number = size * size;
  3. var pixels:Vector.<uint> = new Vector.<uint>();
  4. var r:uint;
  5. var g:uint;
  6. var b:uint;
  7.  
  8. var canvas:BitmapData = new BitmapData(size,size,false,0x000000);
  9. addChild(new Bitmap(canvas));
  10.  
  11. addEventListener(Event.ENTER_FRAME, onLoop);
  12. function onLoop(evt:Event):void {
  13.  
  14.     canvas.lock();
  15.  
  16.     // do any kind of pixel manipulation here:
  17.    
  18.     for (var i:int = 0; i<pixelNum; i++) {
  19.         // draw a gradient that changes based on
  20.         // mouse position
  21.         r = i % size + mouseX;
  22.         b = i / size + mouseY;
  23.         g = (r + b) % mouseX;
  24.         pixels[i] = r <<16 | g <<8 | b;
  25.     }
  26.     canvas.setVector(canvas.rect, pixels);
  27.     //
  28.  
  29.     canvas.unlock();
  30. }

Using BitmapData.lock() and BitmapData.unlock() can speed up BitmaData drawing operations significantly. Simply lock your BitmapData before you draw to it, and unlock it when your done.

I often forget to do this until I get to the optimize phase of a project... but I think I'd like to get in the habit of doing it all the time....

Also posted in BitmapData | Tagged , | 2 Comments

Quadratic Bezier

Actionscript:
  1. var canvas:BitmapData=new BitmapData(280,280,false,0x000000);
  2. addChild(new Bitmap(canvas, PixelSnapping.AUTO, true));
  3. var color:uint;
  4. // anchor x1, anchor y1,
  5. // control-handle x2, control-handle y2,
  6. // anchor x3, anchor y3, [resolution incremental value between 0-1]
  7. function quadBezier(x1:Number, y1:Number, x2:Number, y2:Number, x3:Number, y3:Number, resolution:Number=.03):void {
  8.     var b:Number,pre1:Number,pre2:Number,pre3:Number,pre4:Number;
  9.     for (var a:Number = 0; a <1;a+=resolution) {
  10.    
  11.         b=1-a;
  12.         pre1=(a*a);
  13.         pre2=2*a*b;
  14.         pre3=(b*b);
  15.        
  16.         canvas.setPixel(pre1*x1 + pre2*x2  + pre3*x3 ,
  17.                                      pre1*y1 + pre2*y2 + pre3*y3, color);
  18.     }
  19. }
  20.  
  21. // draw a few
  22. color = 0xFFFFFF;
  23.  
  24. for (var i:int = 0; i<20; i++){
  25. quadBezier(40,100, 150 , 20 + i * 10 , 200, 100,.01);
  26. }
  27.  
  28. color = 0xFF0000;
  29.  
  30. for (i= 0; i<20; i++){
  31. quadBezier(150,200, 100 + i * 10, 100  , 120, 30,.01);
  32. }

The above demos a function that draws quadratic bezier curves using setPixel().

One of the first posts on this site was a snippet that used setPixel() to draw a cubic bezier curve. I recently needed to do the exact same thing but I wanted to use a quadratic bezier... I knew I had the code laying around somewhere, but I couldn't seem to find it so I just looked on wikipedia and changed the previous cubicBezier() function accordingly.

Also posted in BitmapData, bezier, graphics algorithms, setPixel | Tagged , , | 2 Comments