// 360度パノラマ写真を変換するツールです // bloggie http://www.amazon.co.jp/exec/obidos/ASIN/B003479I0Y/nitoyoncom-22/ // 用に作ってますが、他のカメラやレンズにも対応できると思います。 //---- // This tool convert 360 degree photo. // Click LOAD to convert your original 360 degree photo. // Click PREVIEW to preview the result. // Click SAVE to save the result to your computer. package{ import flash.display.*; import flash.text.*; import flash.events.*; import flash.system.LoaderContext; import flash.net.*; import mx.graphics.codec.JPEGEncoder; import com.bit101.components.*; public class Test extends Sprite{ private const SIZE:Number = 450; public function Test() { // load image var loader:Loader = new Loader(); var context:LoaderContext = new LoaderContext(true); loader.load(new URLRequest("http://assets.wonderfl.net/images/related_images/b/bc/bc7b/bc7b2486d569ce97bd1218d3934743214c0c2c99"), context); loader.contentLoaderInfo.addEventListener("complete", loadCompleteHandler); // start text var t:TextField = new TextField(); t.text = "LOADING..."; addChild(t); } private function loadCompleteHandler(event:Event):void { var loaderInfo:LoaderInfo = LoaderInfo(event.target); var bmd:BitmapData = new BitmapData(loaderInfo.width, loaderInfo.height); bmd.draw(loaderInfo.loader); show(bmd); } private function show(bmd:BitmapData):void { // remove all while (numChildren) { removeChildAt(0); } // get size information var w:Number = bmd.width; var h:Number = bmd.height; var scale:Number = Math.min(SIZE / w, (SIZE - 100) / h); var previewOrig:Sprite = addChild(new Sprite()) as Sprite; var previewRes:Sprite = addChild(new Sprite()) as Sprite; var bmp:Bitmap = new Bitmap(bmd); previewOrig.addChild(bmp); bmp.scaleX = bmp.scaleY = scale; var overlay:Sprite = new Sprite(); overlay.scaleX = overlay.scaleY = scale; previewOrig.addChild(overlay); var centerX:Number = w / 2 - 11; var centerY:Number = h / 2; var r1:Number = Math.min(96, h / 2); var r2:Number = Math.min(343, h / 2); var yy:int = h * scale; var xSlider:HUISlider = new HUISlider(previewOrig, 0, yy += 16, "Center X", function(event:Event):void { centerX = w / 2 + xSlider.value; drawOverlay(); }); xSlider.width = SIZE; xSlider.minimum = -w / 2; xSlider.maximum = w / 2; xSlider.value = centerX - w / 2; var ySlider:HUISlider = new HUISlider(previewOrig, 0, yy += 16, "Center Y", function(event:Event):void { centerY = h / 2 + ySlider.value; drawOverlay(); }); ySlider.width = SIZE; ySlider.minimum = -h / 2; ySlider.maximum = h / 2; ySlider.value = centerY - h / 2; var r1Slider:HUISlider = new HUISlider(previewOrig, 0, yy += 16, "R1", function(event:Event):void { r1 = r1Slider.value; drawOverlay(); }); r1Slider.width = SIZE; r1Slider.minimum = 0; r1Slider.maximum = h / 2; r1Slider.value = r1; var r2Slider:HUISlider = new HUISlider(previewOrig, 0, yy += 16, "R2", function(event:Event):void { r2 = r2Slider.value; drawOverlay(); }); r2Slider.width = SIZE; r2Slider.minimum = 0; r2Slider.maximum = h / 2; r2Slider.value = r2; var loadButton:PushButton = new PushButton(this, 0, yy += 16, "LOAD", function(event:Event):void { var file:FileReference = new FileReference(); file.addEventListener(Event.SELECT, function(e:Event):void { file.addEventListener(Event.COMPLETE, function(event:Event):void { var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener("complete", loadCompleteHandler); loader.loadBytes(file.data); }); file.load(); }); file.browse(); }); var previewButton:PushButton = new PushButton(this, 110, yy, "PREVIEW", function(event:Event):void { if (previewRes.numChildren == 0) { var resultBmd:BitmapData = convert(bmd, r1, r2, centerX, centerY); previewRes.scaleX = previewRes.scaleY = previewOrig.height / resultBmd.height; previewRes.addChild(new Bitmap(resultBmd)); previewRes.addChild(new Bitmap(resultBmd)).x = -resultBmd.width; previewRes.addEventListener("enterFrame", function(event:Event):void { if (previewRes.numChildren == 0 || previewRes.parent == null) { previewRes.removeEventListener("enterFrame", arguments.callee); return; } previewRes.x -= (stage.mouseX - SIZE / 2) / 10 - previewRes.width; previewRes.x %= previewRes.width / 2; }); previewButton.label = "CLOSE PREVIEW"; } else { while (previewRes.numChildren) previewRes.removeChildAt(0); previewButton.label = "PREVIEW"; } }); var saveButton:PushButton = new PushButton(this, 220, yy, "SAVE", function(event:Event):void { var resultBmd:BitmapData = convert(bmd, r1, r2, centerX, centerY); var enc:JPEGEncoder = new JPEGEncoder(90); new FileReference().save(enc.encode(resultBmd), "out.jpg"); }); drawOverlay(); function drawOverlay():void { overlay.graphics.clear(); overlay.graphics.lineStyle(0, 0xff0000); overlay.graphics.moveTo(centerX - 10, centerY - 10); overlay.graphics.lineTo(centerX + 10, centerY + 10); overlay.graphics.moveTo(centerX - 10, centerY + 10); overlay.graphics.lineTo(centerX + 10, centerY - 10); overlay.graphics.drawCircle(centerX, centerY, r1); overlay.graphics.drawCircle(centerX, centerY, r2); } } private function convert(bmd:BitmapData, r1:Number, r2:Number, centerX:Number, centerY:Number):BitmapData { // get size information var w:Number = bmd.width; var h:Number = bmd.height; // init convert target BitmapData var H:Number = r2 - r1; var W:Number = r2 * Math.PI; var bmd2:BitmapData = new BitmapData(W, H, false, 0xff808080); // convert to polar coordinates for (var i:int = 0; i < W; i++){ var rad:Number = 2 * Math.PI / W * -i; var cos:Number = Math.cos(rad); var sin:Number = Math.sin(rad); for (var j:int = 0; j <= H; j++){ var xx:int = centerX + (j + r1) * cos; var yy:int = centerY + (j + r1) * sin; bmd2.setPixel(i, j, bmd.getPixel(xx, yy)); } } return bmd2; } } } Donut shaped 360 degree photo (panorama photo) converter