ブラウン管のテレビっぽく画像を表示

(サンプル一覧を表示する)

FlashDevelop を使って、ブラウン管のテレビっぽく画像を表示するテストをしてみました。

線数を間引くことによって、垂直の解像度の荒さを表現しています。
また、2 枚の画像を用意して、それぞれ 1 ピクセルずらして表示することで
インターレス表示のような感じを出しています。

ほんとは動いてる画面に対して処理をかけようと思っていましたが、
難しそうなのでやめました。

テレビというなら 60 フレーム/秒で表示すべきところですが、
Flash の描画が、60 フレーム/秒に間に合わないようなので、
30 フレーム/秒で表示しています。

写真素材は、LittleHut さんからお借りしました。
Flash の実行画面
ブラウン管のテレビっぽく画像を表示

Flashプレーヤーが入っていないか、JavaScriptが無効になっているようです。

Get Adobe Flash player

ブラウン管のテレビっぽく画像を表示
静止画なので、ゆれが気になるようになってしまいました。
ビデオデッキで一時停止ボタンを押した時のような表示だと思って見てくださいw

ソースコード

package 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.BitmapFilterQuality;
	import flash.filters.BlurFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;
	
	/**
	 * ブラウン管のテレビっぽく画像を表示するサンプル
	 * @author Hikipuro
	 */
	public class Main extends Sprite 
	{
		/**
		 * 埋め込み画像
		 */
		[Embed(source='../image/test001.jpg')]
		private var image:Class;
		
		/**
		 * 埋め込み画像のビットマップ
		 * (これは直接画面に表示されません)
		 */
		private var sourceBitmap:Bitmap;
			
		/**
		 * 表示用ビットマップ 1
		 */
		private var bitmap1:Bitmap;
		
		/**
		 * 表示用ビットマップ 2
		 */
		private var bitmap2:Bitmap;
		
		/**
		 * コンストラクタ
		 */
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		/**
		 * 初期化メソッド
		 * @param	e
		 */
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			// 埋め込み画像をいったんビットマップ形式に変換
			sourceBitmap = Bitmap(new image);
			
			// 表示用の 2 枚の画像を作成
			// フレームごとに切り替える
			var bitmapData1:BitmapData;
			var bitmapData2:BitmapData;
			bitmapData1 = new BitmapData(
								sourceBitmap.width, 
								sourceBitmap.height);
			bitmapData2 = new BitmapData(
								sourceBitmap.width, 
								sourceBitmap.height);
			
			// 表示用の画像に元のビットマップをコピー
			// 2 枚目は 1 ピクセル下にずらす
			var matrix:Matrix
			matrix = new Matrix(1, 0, 0, 1, 0, 0);
			bitmapData1.draw(sourceBitmap, matrix);
			
			matrix = new Matrix(1, 0, 0, 1, 0, 1);
			bitmapData2.draw(sourceBitmap, matrix);
			
			// 線の隙間のようなものを描く
			// 色は灰色 (0x202020)
			for (var y:int = 0; y < sourceBitmap.height; y += 4)
			{
				for (var x:int = 0; x < sourceBitmap.width; x++)
				{
					bitmapData1.setPixel(x, y, 0x202020);
					bitmapData2.setPixel(x, y, 0x202020);
				}
			}
			
			// 線が目立ちすぎるので、2x2 サイズの平滑化フィルターをかける
			var blurFilter:BlurFilter;
			blurFilter = new BlurFilter(2, 2, BitmapFilterQuality.HIGH);
			bitmapData1.applyFilter(bitmapData1, bitmapData1.rect, new Point(), blurFilter);
			bitmapData2.applyFilter(bitmapData2, bitmapData2.rect, new Point(), blurFilter);
			
			// グローバルな変数に画像の参照を保存
			bitmap1 = new Bitmap(bitmapData1);
			bitmap2 = new Bitmap(bitmapData2);
			
			// 1 枚目は非表示、2 枚目は表示
			bitmap1.visible = false;
			bitmap2.visible = true;
			
			// 表示する画像をステージに登録
			addChild(bitmap1);
			addChild(bitmap2);
			
			// ステージ開始時イベントを登録
			// ゆれが気になる場合は、これをコメントアウトしてください。
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		/**
		 * フレーム開始イベント
		 * @param	event
		 */
		private function onEnterFrame(event:Event):void 
		{
			// 1 枚目と 2 枚目を切り替える
			bitmap1.visible = !bitmap1.visible;
			bitmap2.visible = !bitmap2.visible;
		}
		
	}
	
}
		

外部リンク