AS3で色相、彩度、明度、コントラストを変化させる時にどんな方法があるかを調べたら、ColorMatrixというクラスを使うと良いらしいとのことだったので、試してみた。
ColorMatrix自体が色を変化させる機能を持つわけではない。
色を変化させるのはColorMatrixFilterで、それ向けの行列を生成するのが、ColorMatrixだ。
ColorMatrixFilterは4×5の行列を使って設定するのだが、彩度、明度あたりはともかく、色相を変化させる行列を書くのはなんか難しそう。さらには行列の乗算とか、めんどくさくてしょうがない。
そこを処理してくれるのが、ColorMatrix。
処理の流れ
処理としては次のようになる。
ColorMatrixに色相、彩度、明度、コントラストを設定
↓
ColorMatrixFilterに結果を渡す
↓
DisplayObject.filtersとかで設定
↓
色が変わった!
fl.motion.ColorMatrix
こんな便利クラスなんだけど、日頃FlashDevelopを使っているのでColorMatrixの存在も知らなかった。
それもそのはず、fl.motionのパッケージ内にあるので、FlexSDKからは使えないのだ。
なので、FlashDevelopで使いたい時には、flash.swcを持ってきて使うことになる。
Windowsだと、FlashIDEをインストールしてあれば次のようなパスで存在する。
C:\Program Files\Adobe\Adobe Flash CS6\Common\Configuration\ActionScript 3.0\libs\flash.swc
おまけ
ColorMatrixと継承もとのDynamicMatrix、同じような目的で使うAdjustColorはなぜかメソッドが大文字から始まっている。
あと、Multiplyメソッドの二番目の引数がリファレンスでは初期値を持たないように書かれているけど、0の初期値を持つようになっている。コード補完で出る名前も違う。
コーディングルールやリファレンスの書式が整備される前に書かれたんだろうか。
参考
actionscript – fl.motion cannot be found with Flex SDK 4.1 – Stack Overflow
http://stackoverflow.com/questions/3697649/fl-motion-cannot-be-found-with-flex-sdk-4-1
クリエイトウェーブ開発日記 ActionScript3.0で色相、彩度、明度、コントラストをいじる
http://createwave.blog104.fc2.com/?mode=m&no=189
[sourcecode language=”as3″]
package
{
import com.bit101.components.HSlider;
import com.bit101.components.Label;
import fl.motion.ColorMatrix;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.ColorMatrixFilter;
import flash.geom.Point;
/**
*
* ◆参考
* actionscript – fl.motion cannot be found with Flex SDK 4.1 – Stack Overflow
* http://stackoverflow.com/questions/3697649/fl-motion-cannot-be-found-with-flex-sdk-4-1
*
* クリエイトウェーブ開発日記 ActionScript3.0で色相、彩度、明度、コントラストをいじる
* http://createwave.blog104.fc2.com/?mode=m&no=189
* …
* @author umhr
*/
public class Main extends Sprite
{
[Embed(source = "lena.jpg", mimeType = "image/jpg")]
private var EmbedClass:Class;
private var _bitmap:Bitmap;
private var _embededBitmapData:BitmapData;
private var _brightnessHSlider:HSlider;
private var _contrastHSlider:HSlider;
private var _hueHSlider:HSlider;
private var _saturationHSlider:HSlider;
private var _brightnessLabel:Label;
private var _contrastLabel:Label;
private var _hueLabel:Label;
private var _saturationLabel:Label;
public function Main()
{
init();
}
private function init():void
{
if (stage) onInit();
else addEventListener(Event.ADDED_TO_STAGE, onInit);
}
private function onInit(event:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, onInit);
// entry point
var bitmap:Bitmap = new EmbedClass() as Bitmap;
_bitmap = new Bitmap(new BitmapData(bitmap.width, bitmap.height));
addChild(_bitmap);
_embededBitmapData = bitmap.bitmapData.clone();
addUI();
onBrightness(null);
}
private function addUI():void
{
// 明度
_brightnessHSlider = new HSlider(this, 10, 10, onBrightness);
_brightnessHSlider.maximum = 255;
_brightnessHSlider.minimum = -256;
_brightnessHSlider.value = 0;
_brightnessLabel = new Label(this, 112, 10 – 4, "Brightness:0");
// コントラスト
_contrastHSlider = new HSlider(this, 10, 30, onBrightness);
_contrastHSlider.maximum = 255;
_contrastHSlider.minimum = -256;
_contrastHSlider.value = 127;
_contrastLabel = new Label(this, 112, 30 – 4, "Contrast:127");
// 色相
_hueHSlider = new HSlider(this, 10, 50, onBrightness);
_hueHSlider.maximum = 3.14;
_hueHSlider.minimum = -3.14;
_hueHSlider.value = 0;
_hueLabel = new Label(this, 112, 50 – 4, "Hue:0");
// 彩度
_saturationHSlider = new HSlider(this, 10, 70, onBrightness);
_saturationHSlider.maximum = 2;
_saturationHSlider.minimum = -1;
_saturationHSlider.value = 1;
_saturationLabel = new Label(this, 112, 70 – 4, "Saturation:1");
}
private function onBrightness(event:Event):void
{
var colorMatrix:ColorMatrix = new ColorMatrix();
// 次のような記述だと、後に設定した値に上書きされてしまうので、
// 複数の処理をする場合には適さない。
//colorMatrix.SetBrightnessMatrix(_brightnessHSlider.value);
//colorMatrix.SetContrastMatrix(_contrastHSlider.value);
//colorMatrix.SetHueMatrix(_hueHSlider.value);
//colorMatrix.SetSaturationMatrix(_saturationHSlider.value);
var brightnessColorMatrix:ColorMatrix = new ColorMatrix();
brightnessColorMatrix.SetBrightnessMatrix(_brightnessHSlider.value);
_brightnessLabel.text = "Brightness:" + _brightnessHSlider.value;
var contrastColorMatrix:ColorMatrix = new ColorMatrix();
contrastColorMatrix.SetContrastMatrix(_contrastHSlider.value);
_contrastLabel.text = "Contrast:" + _contrastHSlider.value;
var hueColorMatrix:ColorMatrix = new ColorMatrix();
hueColorMatrix.SetHueMatrix(_hueHSlider.value);
_hueLabel.text = "Hue:" + _hueHSlider.value;
var saturationColorMatrix:ColorMatrix = new ColorMatrix();
saturationColorMatrix.SetSaturationMatrix(_saturationHSlider.value);
_saturationLabel.text = "Saturation:" + _saturationHSlider.value;
// 複数の処理をする場合は、行列の乗算をする。
colorMatrix.Multiply(brightnessColorMatrix);
colorMatrix.Multiply(contrastColorMatrix);
colorMatrix.Multiply(hueColorMatrix);
colorMatrix.Multiply(saturationColorMatrix);
var colorMatrixFilter:ColorMatrixFilter = new ColorMatrixFilter();
var flatMatrix:Array = colorMatrix.GetFlatArray();
colorMatrixFilter.matrix = flatMatrix;
_bitmap.bitmapData.applyFilter(_embededBitmapData, _embededBitmapData.rect, new Point(), colorMatrixFilter.clone());
// DisplayObject には次のような書き方をする。
//_bitmap.filters = [colorMatrixFilter];
}
}
}
[/sourcecode]
1 Comment
色を変化を部分的に適応出来たりしたら面白そう。
画像とパラメータを投げると加工された画像がダウンロード出来るサービスとかがあるといいのになぁ。
描画APIはやっぱり Flash が強いですね