こんばんは。きんくまです。
えーと先週はエヴァの破とお台場のガンダム見てきました。
どっちも面白かったです。特に破はすごいです。すごすぎです。
画面の密度が濃いです。あと、TV版はもう関係ないんですね。
話は完全にオリジナルになってました。だから序よりも断然面白いですね。
ガンダムの方は良かったんですが、なんというか「思ったよりも小さかった。」
というのが正直な感想です。いや、決して悪かったわけではありません。
むしろ細かいところまでよくできていまして、ガンプラをそのままひきのばしたような精巧さ。といいますか。
あの大きさだったら、次回はもっと大胆に動かして欲しいなあ、と。
無理か、、。
さて、RGBとHSVの変換です。
クラゲ時計ではRGBとHSVの変換を下記の本から移植したクラスを使っています。
>> 詳解 画像処理プログラミング / 昌達 慶仁 著 / ソフトバンククリエイティブ
このクラスを使うとRGBとHSVの変換をしても情報が劣化しないです。
そのかわりHSVのとる値が変わっていて
H : 0 ~ 3066
S : 0 ~ 511
V : 0 ~ 511
となっています。すべてint型です。
デモは単純なカラーピッカーだけだとさみしいので、モザイク処理もつけてみました。
モザイク処理はもととなる画像をMatrixをつかって拡大するとできます。
以下ソースです。
package { import com.kuma_de.ColorUtil; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.MovieClip; import flash.display.Sprite; import flash.display.Stage; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; import flash.text.TextField; import flash.ui.Mouse; import flash.utils.getDefinitionByName; public class Main extends Sprite { public var spoit:MovieClip; public var photo:MovieClip; public var photoBmd:BitmapData; public var isSpoitCursor:Boolean = false; public var currentColorBmd:BitmapData; public var currentX:Number; public var currentY:Number; public var currentColor:int; public var h:TextField; public var s:TextField; public var v:TextField; public var r:TextField; public var g:TextField; public var b:TextField; public var mozaicBmd:BitmapData; public var mozaicSrcBmd:BitmapData; public function Main() { init(); spoit.visible = false; this.stage.addEventListener(Event.ENTER_FRAME, update); } private function update(e:Event):void { var t:Stage = e.currentTarget as Stage; currentX = t.mouseX; currentY = t.mouseY; var hitTestFlag:Boolean = photoBmd.hitTest(new Point(5, 5), 0, new Point(currentX, currentY)); if (hitTestFlag) { setCurrentColor(); setColorText(); setMozaic(); setSpoitCursor(true); }else { setSpoitCursor(false); } } private function setSpoitCursor(isSpoit:Boolean):void { if (isSpoit) { Mouse.hide(); spoit.visible = true; isSpoitCursor = true; spoit.x = currentX; spoit.y = currentY; }else { Mouse.show(); spoit.visible = false; isSpoitCursor = false; } } private function setCurrentColor():void { var pt:Point = photo.globalToLocal(new Point(currentX, currentY)); currentColor = photoBmd.getPixel(pt.x, pt.y); currentColorBmd.fillRect(currentColorBmd.rect, currentColor); } private function init():void { var myc:Class = getDefinitionByName("photo") as Class; var b:BitmapData = new myc(0, 0); photoBmd = new BitmapData(b.width + 10, b.height + 10, true, 0); photoBmd.copyPixels(b, b.rect, new Point(5, 5)); photo = new MovieClip(); photo.addChild(new Bitmap(photoBmd)); photo.x = 5; photo.y = 5; this.addChild(photo); currentColorBmd = new BitmapData(25, 25, false, 0xff000000); var curBm:Bitmap = new Bitmap(currentColorBmd); this.addChild(curBm); curBm.x = 227; curBm.y = 59; mozaicBmd = new BitmapData(70, 70, true, 0xffffffff); var moB:Bitmap = new Bitmap(mozaicBmd); moB.x = 309; moB.y = 19; this.addChild(moB); mozaicSrcBmd = new BitmapData(7, 7); initColorText(); setChildIndex(spoit, numChildren - 1); } private function initColorText():void { h.text = ""; s.text = ""; v.text = ""; r.text = ""; g.text = ""; b.text = ""; } private function setColorText():void { var rgb:Vector.<int> = ColorUtil.HextoRGB(currentColor); var hsv:Vector.<int> = ColorUtil.RGBtoHSV(rgb[0], rgb[1], rgb[2]); h.text = hsv[0].toString(); s.text = hsv[1].toString(); v.text = hsv[2].toString(); r.text = rgb[0].toString(); g.text = rgb[1].toString(); b.text = rgb[2].toString(); } private function setMozaic():void { var pt:Point = photo.globalToLocal(new Point(currentX, currentY)); mozaicSrcBmd.fillRect(mozaicSrcBmd.rect, 0xffffffff); var b:BitmapData = mozaicSrcBmd.clone(); b.fillRect(b.rect, 0xff000000); mozaicSrcBmd.copyPixels( photoBmd, new Rectangle(pt.x - 3, pt.y - 3, 7, 7), new Point(0, 0), b, new Point(0, 0), true ); var mtx:Matrix = new Matrix(); mtx.scale(10, 10); mozaicBmd.draw(mozaicSrcBmd, mtx); } } }
こっちが移植したクラスです。あと、16進数の変換のあたりは勝手につけといた。
/* * Cの書籍からの移植 * 詳解 画像処理プログラミング / 昌達 慶仁 著 / ソフトバンククリエイティブ * http://www.sbcr.jp/books/products/detail.asp?sku=4797344370 */ package com.kuma_de { public class ColorUtil { private static const SCALE:Number = 255; private static const hSCALE:Number = 256; private static const GETA:Number = 2; private static const hGETA:Number = 2; /** * RGBからHSVを得る * * @param r Red 0~255 * @param g Green 0~255 * @param b Blue 0~255 * @return Vector.<int> H:0~3066, S:0~511, V:0~511 */ public static function RGBtoHSV(r:int, g:int, b:int):Vector.<int> { var rr:Number, gg:Number, bb:Number; var hh:Number, ss:Number, vv:Number; var cmax:Number, cmin:Number, cdes:Number; rr = Number(r); gg = Number(g); bb = Number(b); cmax = (rr > gg) ? rr : gg; if (bb > cmax) { cmax = bb; } cmin = (rr < gg) ? rr : gg; if (bb < cmin) { cmin = bb; } cdes = cmax - cmin; vv = cmax; if (cdes != 0) { ss = cdes * SCALE / cmax; if (cmax == rr) { hh = (gg - bb) * SCALE / cdes; }else if (cmax == gg) { hh = (bb - rr) * SCALE / cdes + 2 * hSCALE; }else { hh = (rr - gg) * SCALE / cdes + 4 * hSCALE; } }else if (cmax != 0) { ss = cdes * SCALE / cmax; hh = 0; }else { ss = 0; hh = 0; } if (hh < 0) { hh += 6 * hSCALE; } return Vector.<int>([int(hh * hGETA), int(ss * hGETA), int(vv * hGETA)]); } /** * RGBからHSVを得る * * @param h Hue 0~3066 * @param s Saturation 0~511 * @param v Value 0~511 * @return Vector.<int> R:0~255, G:0~255, B:0~255 */ public static function HSVtoRGB(h:int, s:int, v:int):Vector.<int> { var rr:Number, gg:Number, bb:Number; var hh:Number, ss:Number, vv:Number; var r:Number, g:Number, b:Number; if (h == 6 * hGETA * hSCALE) { h = 0; } hh = Number(h / hGETA); ss = Number(s / GETA); vv = Number(v / GETA); switch(int(hh / hSCALE)) { case 0: rr = SCALE; gg = hh; bb = 0; break; case 1: rr = 2 * hSCALE - hh; gg = SCALE; bb = 0; break; case 2: rr = 0; gg = SCALE; bb = hh - 2 * hSCALE; break; case 3: rr = 0; gg = 4 * hSCALE - hh; bb = SCALE; break; case 4: rr = hh - 4 * hSCALE; gg = 0; bb = SCALE; break; case 5: rr = SCALE; gg = 0; bb = 6 * hSCALE - hh; break; } rr = (rr + (SCALE - rr) * (SCALE - ss) / SCALE) * vv / SCALE; gg = (gg + (SCALE - gg) * (SCALE - ss) / SCALE) * vv / SCALE; bb = (bb + (SCALE - bb) * (SCALE - ss) / SCALE) * vv / SCALE; r = int(rr); g = int(gg); b = int(bb); if (r > 255) { r = 255 } if (g > 255) { g = 255 } if (b > 255) { b = 255 } return Vector.<int>([r, g, b]); } private static function sgn(x:Number):Number { return (x < 0) ? -1 : 1; } private static function CINT(x:Number):int { return int(x + sgn(x) * 0.5); } private static var FL:Number; //ここから追加した分 /** * RGBから16進数を得る * * @param r Red 0~255 * @param g Green 0~255 * @param b Blue 0~255 * @return int 0~0xffffff */ public static function RGBtoHex(r:int, g:int, b:int):int { return r << 16 | g << 8 | b; } /** * ARGBから16進数を得る * * @param a Alpha 0~255 * @param r Red 0~255 * @param g Green 0~255 * @param b Blue 0~255 * @return int 0~0xffffffff */ public static function ARGBtoHex(a:int, r:int, g:int, b:int):int { return a << 24 | r << 16 | g << 8 | b; } /** * 16進数からRGBを得る * * @param hex 16進数 * @return Vector.<int> R:0~255, G:0~255, B:0~255 */ public static function HextoRGB(hex:int):Vector.<int> { var r:int = hex >> 16; var g:int = hex >> 8 & 0xff; var b:int = hex & 0xff; return Vector.<int>([r, g, b]); } /** * 16進数からRGBを得る * * @param hex 16進数 * @return Vector.<int> A:0~255, R:0~255, G:0~255, B:0~255 */ public static function HextoARGB(hex:int):Vector.<int> { var a:int = hex >> 24; var r:int = hex >> 16 & 0xff; var g:int = hex >> 8 & 0xff; var b:int = hex & 0xff; return Vector.<int>([a, r, g, b]); } } }
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ