円柱HSV空間 forked from: 画像のHSV解析
/**
* Copyright sowcodWonderfl ( http://wonderfl.net/user/sowcodWonderfl )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/gvEg
*/
// forked from sowcodWonderfl's 画像のHSV解析
package
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.display.Graphics;
import flash.system.Security;
import org.papervision3d.view.BasicView;
import org.papervision3d.core.proto.CameraObject3D;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.materials.special.ParticleMaterial;
import org.papervision3d.core.geom.Particles;
import org.papervision3d.core.geom.renderables.Particle;
[SWF(backgroundColor="0x666699", frameRate="24")]
public class HSVAnalyzer extends Sprite
{
// 読み込んだ画像のピクセルをそれぞれHSVに変換して、
// 円錐HSV空間にパーティクルとして散りばめています。
// 画像の色構成がよくわかる。
public static const urlList:Array = [
"http://farm3.static.flickr.com/2612/3711632843_19baf94aac.jpg",
"http://farm3.static.flickr.com/2720/4103685834_8f837f27e6.jpg",
"http://farm4.static.flickr.com/3378/3273728483_cb87317283.jpg",
"http://farm3.static.flickr.com/2481/3545692688_ce4c7c1c8b.jpg",
"http://farm4.static.flickr.com/3548/3637064374_15e3f83d29.jpg"
];
private var view:BasicView;
private var pField:Particles;
private var image:AnalyzedImageData;
private var cnt:Number;
private var imageNum:int;
public function HSVAnalyzer()
{
this.view = new BasicView();
this.addChild(this.view.viewport);
this.view.startRendering();
this.pField = new Particles();
this.pField.y = -100;
this.view.scene.addChild(this.pField);
this.view.camera.target = this.pField;
// 解析解像度を設定し、ロードが完了したら自動的にパーティクルを生成するようにする
image = new AnalyzedImageData(50,50);
image.addEventListener(Event.COMPLETE,function(ev:Event):void {
image.scaleX = image.scaleY = image.rate * 3;
setupParticles(image.hsvList);
});
this.addChild(image);
// クリックできるエリア作る
var hitSpriteDummy:Sprite = new Sprite();
var hitSprite:Sprite = this.createHitArea();
hitSpriteDummy.addChild(hitSprite);
hitSpriteDummy.hitArea = hitSprite;
this.addChild(hitSpriteDummy)
this.addEventListener(MouseEvent.MOUSE_DOWN,function(ev:MouseEvent):void {
loadNextImage();
});
this.cnt = 0;
this.addEventListener(Event.ENTER_FRAME,this.onEnterFrame);
this.loadNextImage();
}
private function loadNextImage():void
{
this.imageNum = (++imageNum) % urlList.length;
image.loadURL(urlList[this.imageNum]);
trace(urlList[this.imageNum]);
}
private function setupParticles(datas:Vector.<HSVData>):void
{
this.pField.removeAllParticles();
var len:Number = datas.length;
for(var i:Number = 0; i < len; ++i) {
var data:HSVData = datas[i];
var material:ParticleMaterial = new ParticleMaterial(data.rgb,1);
var particle:Particle = new Particle(material,5);
particle.x = Math.cos(data.h) * data.s * 200;
particle.z = Math.sin(data.h) * data.s * 200;
particle.y = data.v * 200 - 200;
this.pField.addParticle(particle);
}
}
private function onEnterFrame(ev:Event):void
{
var camera:CameraObject3D = this.view.camera;
camera.x = Math.cos(this.cnt) * 400;
camera.y = 150;
camera.z = Math.sin(this.cnt) * 400;
this.cnt += 0.03;
}
private function createHitArea():Sprite
{
var sp:Sprite = new Sprite();
var g:Graphics = sp.graphics;
g.beginFill(0x000000);
g.drawRect(0,0,this.stage.width,this.stage.height);
g.endFill();
sp.visible = false;
trace(this.stage.width+","+this.stage.height);
return sp;
}
}
}
import flash.display.Loader;
import flash.display.Sprite;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.geom.Matrix;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.events.Event;
import flash.display.Bitmap;
import flash.display.BitmapData;
class HSVData
{
public static const RAD60:Number = Math.PI*2/6;
public var rgb:uint;
public var h:Number;
public var s:Number;
public var v:Number;
public var alpha:Number;
public function HSVData(argb:uint)
{
this.rgb = argb & 0xffffff;
// HSVに変換
var alpha:Number = (argb >> 24 & 0xff) / 0xff;
var r:Number = (argb >> 16 & 0xff) / 0xff;
var g:Number = (argb >> 8 & 0xff) / 0xff;
var b:Number = (argb & 0xff) / 0xff;
var max:Number = Math.max(r,g,b);
var min:Number = Math.min(r,g,b);
if(max == min) {
this.h = 0;
this.s = 0;
} else {
if(max == r) this.h = RAD60*(g-b)/(max-min);
else if(max == g) this.h = RAD60*(b-r)/(max-min) + RAD60*2;
else if(max == b) this.h = RAD60*(r-g)/(max-min) + RAD60*4;
if(h<0) h += Math.PI*2;
this.s = (max-min)/max;
}
this.v = max;
//trace("("+alpha+","+r+","+g+","+b+")");
}
}
class AnalyzedImageData extends Bitmap
{
public var hsvList:Vector.<HSVData>;
public var maxWidth:Number;
public var maxHeight:Number;
public var rate:Number;
public var smallBitmapData:BitmapData;
public function AnalyzedImageData(maxWidth:Number,maxHeight:Number)
{
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
hsvList = new Vector.<HSVData>();
}
public function loadURL(url:String):void
{
var context:LoaderContext = new LoaderContext(true);
var self:AnalyzedImageData = this;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,
function(ev:Event):void {
if(loader.width > loader.height) rate = maxWidth / loader.width;
else rate = maxHeight / loader.height;
self.bitmapData = new BitmapData(loader.width, loader.height,true);
self.smallBitmapData = new BitmapData(loader.width * rate, loader.height * rate, true);
self.smallBitmapData.draw(loader,new Matrix(rate,0,0,rate));
self.bitmapData.draw(loader);
self.analyze();
});
loader.load(new URLRequest(url),context);
}
private function analyze():void
{
this.hsvList = new Vector.<HSVData>();
var maxw:Number = this.bitmapData.width * rate;
var maxh:Number = this.bitmapData.height * rate;
for(var x:Number = 0; x<maxw; ++x) {
for(var y:Number = 0; y<maxh; ++y) {
this.hsvList.push(new HSVData(this.smallBitmapData.getPixel32(x,y)));
}
}
this.dispatchEvent(new Event(Event.COMPLETE));
}
}