輝度アルファ変換もどき

by tkinjo
♥0 | Line 80 | Modified 2009-05-23 16:06:50 | MIT License
play

ActionScript3 source code

/**
 * Copyright tkinjo ( http://wonderfl.net/user/tkinjo )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/9kPm
 */

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="465" height="465" paddingLeft="0" paddingTop="0" paddingRight="0" paddingBottom="0"
		applicationComplete="applicationCompleteHandler( event )">
	
	<mx:Script>
		<![CDATA[
			
			import flash.display.Bitmap;
			import flash.display.BitmapData;
			import flash.display.Loader;
			import flash.display.LoaderInfo;
			import flash.geom.ColorTransform;
			import flash.geom.Point;
			import flash.net.FileFilter;
			import flash.net.FileReference;
			import mx.controls.ColorPicker;
			import mx.controls.HSlider;
			import mx.events.EffectEvent;
			import mx.events.FlexEvent;
			
			/**
			 * 輝度アルファ変換もどき
			 * 
			 * 輝度アルファ変換の正しいアルゴリズムがわかりません。
			 * このやりかたは inkscape の Luminance to Alpha を適用した時と同じ結果を出すように試行錯誤して見つけたものです。
			 * …つまり適当。
			 * 結果はほとんど同じですが、まったく同じではないので。
			 * だれか正しいやり方を知っていたら、ぜひ fork をお願いします。
			 */
			
			/**
			 * FileReference
			 */
			private var fileReference:FileReference;
			
			/**
			 * 読み込んだ画像
			 */
			private var loadedBitmap:Bitmap;
			
			/**
			 * 初期設定をします。
			 * 
			 * @param	event
			 */
			private function applicationCompleteHandler( event:Event ):void {
				
				canvasBackgroundColorPicker.selectedColor = canvas.getStyle( "backgroundColor" );
				attachParlinNoiseBitmap();
				
				luminanceToAlpha();
			}
			
			/**
			 * 輝度アルファ変換もどき(てきとー)
			 */
			private function luminanceToAlpha():void {
				
				/**
				 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
				 * ここで透過される bitmapData ( transparent = true, fillColor = 0x00xxxxxx )を用意する。
				 * もし tempBitmapData = loadedBitmap.bitmapData としてしまうと、jpeg だと真っ黒。
				 * gif でも透過 gif 以外だと真っ黒になってしまう。
				 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
				 */
				var tempBitmapData:BitmapData = new BitmapData( loadedBitmap.width, loadedBitmap.height, true, 0 );
				tempBitmapData.draw( loadedBitmap.bitmapData );
				
				// グレースケールに変換
				//*
				tempBitmapData.applyFilter( tempBitmapData, tempBitmapData.rect, new Point(), new ColorMatrixFilter( [
						0.33, 	0.33, 	0.33, 	0, 		0, 
						0.33, 	0.33, 	0.33, 	0, 		0, 
						0.33, 	0.33, 	0.33, 	0, 		0, 
						0, 		0, 		0, 		1, 		0
					] ) );
				//*/
				
				// 反転
				//*
				tempBitmapData.applyFilter( tempBitmapData, tempBitmapData.rect, new Point(), new ColorMatrixFilter( [
						-1, 		0, 		0,			0,			255, 
						0, 		-1, 		0,			0,			255, 
						0, 		0, 		-1, 		0,			255, 
						0, 		0, 		0, 		1, 		0
					] ) );
				//*/
				
				// 仕上げ
				//*
				tempBitmapData.applyFilter( tempBitmapData, tempBitmapData.rect, new Point(), new ColorMatrixFilter( [
						-1, 		0, 		0,			0,			0, 
						0, 		-1, 		0,			0,			0, 
						0, 		0, 		-1, 		0,			0, 
						-0.33, 	-0.33, 	-0.33, 	1, 		0
					] ) )
				//*/
				/*
				tempBitmapData.applyFilter( tempBitmapData, tempBitmapData.rect, new Point(), new ColorMatrixFilter( [
						-1, 		0, 		0,			0,			255, 
						0, 		-1, 		0,			0,			255, 
						0, 		0, 		-1, 		0,			255, 
						-0.33, 	-0.33, 	-0.33, 	1, 		0
					] ) );
				//*/
				
				loadedBitmap.bitmapData = tempBitmapData;
			}
			
			/**
			 * パーリンノイズの作成と配置
			 */
			private function attachParlinNoiseBitmap():void {
				
				if( loadedBitmap )
					imageContentHolder.removeChild( loadedBitmap );
				
				var perlinNoiseBitmapData:BitmapData = new BitmapData( 400, 400 );
				
				perlinNoiseBitmapData.perlinNoise( 40, 40, 1, 0, false, false, parseInt( "111", 2 ), false, [ new Point( 0, 0 ) ] );
				loadedBitmap = new Bitmap( perlinNoiseBitmapData );
				
				setImageContentHolder();
			}
			
			/**
			 * 開くボタンが押されたときにファイル選択ダイアログボックスを表示します。
			 * 
			 * @param	event
			 */
			private function openButtonDownHandler( event:FlexEvent ):void {
				
				fileReference = new FileReference();
				fileReference.addEventListener( Event.SELECT, fileReferenceSelectHandler );
				var fileFilter:FileFilter = new FileFilter("Images (*.jpg,*.gif,*.png)", "*.jpg;*.gif;*.png");
				fileReference.browse( [ fileFilter ] );
			}
			
			/**
			 * ファイル選択ダイアログボックスでファイルが選択されるとそのファイルを読み込みます。
			 * 
			 * @param	event
			 */
			private function fileReferenceSelectHandler( event:Event ):void {
				
				fileReference.addEventListener( Event.COMPLETE, fileReferenceCompleteHandler );
				fileReference.load();
			}
			
			/**
			 * ファイルが読み込まれると imageContentHolder に画像を配置する準備をします。
			 * 
			 * @param	event
			 */
			private function fileReferenceCompleteHandler( event:Event ):void {
				
				var loader:Loader = new Loader();
				
				loader.contentLoaderInfo.addEventListener( Event.COMPLETE, loaderCompleteHandler );
				
				loader.loadBytes( fileReference.data );
			}
			
			/**
			 * imageContentHolder に画像を配置します。
			 * 
			 * @param	event
			 */
			private function loaderCompleteHandler( event:Event ):void {
				
				if ( loadedBitmap )
					imageContentHolder.removeChild( loadedBitmap );
				
				loadedBitmap = ( event.currentTarget as LoaderInfo ).content as Bitmap;
				
				//var scale:Number = ( loadedBitmap.width > loadedBitmap.height ) ? stage.stageWidth / loadedBitmap.width : stage.stageHeight / loadedBitmap.height;
				//loadedBitmap.scaleX = scale;
				//loadedBitmap.scaleY = scale;
				setImageContentHolder();
				
				luminanceToAlpha();
			}
			
			/**
			 * imageContentHolder の位置を中央に調整し、loadedBitmap を子に登録します。
			 */
			private function setImageContentHolder():void {
				
				imageContentHolder.x = ( stage.stageWidth - loadedBitmap.width ) / 2;
				imageContentHolder.y = ( stage.stageHeight - loadedBitmap.height ) / 2;
				imageContentHolder.addChild( loadedBitmap );
			}
			
			/**
			 * 
			 * @param	event
			 */
			private function canvasBackgroundColorPickerChangeHandler( event:Event ):void {
				
				canvas.setStyle( "backgroundColor", canvasBackgroundColorPicker.selectedColor );
			}
			
		]]>
	</mx:Script>
	
	<mx:Canvas id="canvas" width="100%" height="100%" backgroundColor="0xccccff">
		<mx:UIComponent id="imageContentHolder" />
		<mx:HBox width="100%" alpha="0.9" backgroundColor="0xffffff" paddingLeft="2" paddingTop="2" paddingBottom="2">
			<mx:Button id="openButton" label="画像を開く" buttonDown="openButtonDownHandler( event )" />
			<mx:ColorPicker id="canvasBackgroundColorPicker" change="canvasBackgroundColorPickerChangeHandler( event )" />
		</mx:HBox>
	</mx:Canvas>
	
</mx:Application>