{"id":168,"date":"2009-01-26T00:00:13","date_gmt":"2009-01-26T07:00:13","guid":{"rendered":"https:\/\/actionsnippet.com\/?p=596"},"modified":"2009-01-26T00:00:13","modified_gmt":"2009-01-26T07:00:13","slug":"seamless-tiles","status":"publish","type":"post","link":"https:\/\/actionsnippet.com\/?p=168","title":{"rendered":"Seamless Tiles"},"content":{"rendered":"<pre class=\"brush: as3; title: ; notranslate\" title=\"\">\r\n&#x5B;SWF(width=600, height=500, backgroundColor=0xFFFFFF, frameRate=30)]\r\n\r\nfunction seamlessTile(img:BitmapData, featherSize:Number = 5):BitmapData{\r\n\tvar pnt:Point = new Point(0,0);\r\n\tvar tile:BitmapData = new BitmapData(img.width, img.height, true, 0xFF000000);\r\n\ttile.copyPixels(img, img.rect, pnt, null, null, true);\r\n\t\r\n\tvar flipped:BitmapData = new BitmapData(img.width, img.height, true, 0xFF000000);\r\n\tvar m:Matrix = new Matrix();\r\n\tm.scale(-1, 1);\r\n\tm.translate(tile.width,0);\r\n\tflipped.draw(tile, m);\r\n\t\r\n\tvar aChannel:BitmapData = new BitmapData(img.width, img.height, true, 0x00000000);\r\n\tvar grad:Sprite = new Sprite();\r\n\tm.createGradientBox(img.width, img.height, 0, 0, 0);\r\n\t\r\n\tgrad.graphics.beginGradientFill(GradientType.LINEAR, &#x5B;0xFFFFFF, 0xFFFFFF],  &#x5B;1, 0], &#x5B;0, (255 \/ img.width) * img.width \/ featherSize], m, SpreadMethod.PAD);\r\n\t\r\n\tgrad.graphics.drawRect(0,0,img.width, img.height);\r\n\taChannel.draw(grad);\r\n \r\n\ttile.copyPixels(flipped, flipped.rect, pnt, aChannel, pnt, true);\r\n\t\r\n\tm.identity();\r\n\tm.scale(1, -1);\r\n\tm.translate(0,tile.height);\r\n\tflipped.draw(tile, m)\r\n\t\r\n\taChannel.fillRect(aChannel.rect, 0x00000000);\r\n\tm.createGradientBox(img.width, img.height, Math.PI \/ 2, 0, 0);\r\n\tgrad.graphics.clear();\r\n\tgrad.graphics.beginGradientFill(GradientType.LINEAR, &#x5B;0xFFFFFF, 0xFFFFFF], &#x5B;1, 0], &#x5B;0, (255 \/ img.height) * img.height \/ featherSize],  m, SpreadMethod.PAD);\r\n\t\r\n\tgrad.graphics.drawRect(0,0,img.width, img.height);\r\n\taChannel.draw(grad, grad.transform.matrix);\r\n\t\r\n\ttile.copyPixels(flipped, flipped.rect, pnt, aChannel, pnt, true);\r\n\treturn tile;\r\n}\r\n\r\n\/\/ test out the function:\r\nvar canvas:BitmapData = new BitmapData(600, 470, true, 0xFF000000);\r\naddChild(new Bitmap(canvas));\r\n\r\nvar image:Loader = new Loader();\r\nimage.load(new URLRequest(&quot;https:\/\/actionsnippet.com\/imgs\/paper.jpg&quot;));\r\nimage.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);\r\nvar texture:BitmapData;\r\n\r\nfunction onLoaded(evt:Event):void {\r\n\ttexture =  Bitmap(image.content).bitmapData;\r\n\taddEventListener(Event.ENTER_FRAME, onLoop);\r\n\timage.removeEventListener(Event.COMPLETE, onLoaded);\r\n}\r\n\r\nfunction onLoop(evt:Event):void{\r\n\tvar tile:BitmapData = seamlessTile(texture, Math.max(1,mouseX\/30));\r\n\tvar p:Point = new Point();\r\n\tfor (var i:int = 0; i&lt;8; i++){\r\n\t\tp.x = (i % 4) * tile.width;\r\n\t\tp.y = int(i \/ 4) * tile.height;\r\n\t\tcanvas.copyPixels(tile, tile.rect, p);\r\n\t}\r\n}\r\n<\/pre>\n<p>The above demos a function called seamlessTile() which takes a BitmapData object and uses an oldschool seamless tile technique on it. <\/p>\n<p>The result is that you can have an image that would normally tile like this:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.actionsnippet.com\/imgs\/seam1.jpg\" \/><br \/>\nend up looking like this:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.actionsnippet.com\/imgs\/seam2.jpg\" \/><br \/>\n<a data-asruffle-linked=\"true\" href=\"http:\/\/www.actionsnippet.com\/swfs\/seamless_texture.html\" target=\"blank\"><br \/>\nYou can take a look at the swf here.<\/a> <span class=\"asruffle-link\" data-swf=\"{&quot;url&quot;:&quot;https:\\\/\\\/actionsnippet.com\\\/swfs\\\/seamless_texture.swf&quot;,&quot;title&quot;:&quot;seamless texture&quot;,&quot;width&quot;:600,&quot;height&quot;:500,&quot;missing&quot;:false,&quot;allowScriptAccess&quot;:false,&quot;backgroundColor&quot;:&quot;#ffffff&quot;}\"><button type=\"button\" hidden aria-expanded=\"false\">Play demo<span class=\"screen-reader-text\">: seamless texture<\/span><\/button><\/span><\/p>\n<p>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&#8230;. <\/p>\n<p>There are better seamless tile algorithms out there&#8230;. 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&#8230; <\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#x5B;SWF(width=600, height=500, backgroundColor=0xFFFFFF, frameRate=30)] function seamlessTile(img:BitmapData, featherSize:Number = 5):BitmapData{ var pnt:Point = new Point(0,0); var tile:BitmapData = new BitmapData(img.width, img.height, true, 0xFF000000); tile.copyPixels(img, img.rect, pnt, null, null, true); var flipped:BitmapData = new BitmapData(img.width, img.height, true, 0xFF000000); var m:Matrix = new Matrix(); m.scale(-1, 1); m.translate(tile.width,0); flipped.draw(tile, m); var aChannel:BitmapData = new BitmapData(img.width, img.height, true, 0x00000000); var [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,114,25],"tags":[3,4],"class_list":["post-168","post","type-post","status-publish","format-standard","hentry","category-bitmapdata","category-graphics-algorithms","category-pixel-manipulation","tag-actionscript","tag-flash"],"_links":{"self":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/posts\/168","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=168"}],"version-history":[{"count":0,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/posts\/168\/revisions"}],"wp:attachment":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=168"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}