POPSブログ

CreateJS 画像をトリミング(又は分割)してBitmap処理、Tweenさせる処理を考える

247

  Category:  javascript2013/09/12 pops 

画像をトリミング又は分割して、Tween などさせるには、HTML5、Canvas処理の drawImage() を使用してトリミング、Bitmap化すると便利です。処理の順序さえ覚えれば色々と応用などが利きます。Shape化グラフイック表示も考えてみました。
easeljs-0.7 (easeljs-0.7.0)でのテストです。


2013/09/25/EaselJSなどバージョンUPされました(easeljs-0.7)。動作など確認してeaseljs-0.7用に更新しています。(2013/10/09)


[説明図]

 

1. HTML5、Canvas処理の drawImage() を使用してトリミング(又は分割)する。
2. CreateJSでTwennなどするにはdrawImage()処理後、Bitmap処理してインスタンス化する。
3. drawImage()処理は、画像が完全にロードされた状態でなければ処理出来ませんので注意下さい。
4. toDataURL()を利用しない方法で簡単です。
(toDataURL()を利用する方式は「デモ2」に掲載しています、20013/10/02、変更しました)
5. CreateJS バージョン 0.7.0 使用のものです。
6. CreateJSでの正式なBitmap化処理では有りませんから処理出来ない事も発生します。


DEMO


CreateJS 画像をトリミング(又は分割)してBitmap処理、Tweenさせる例 (createJS035.js)

このページはHTML5では有りませんので、デモページでご覧ください。「IE7.8」ではご覧いただけません。


通常のトリミング「デモ1」


Chrome Firefox Safari(Win) IE9、で動作確認済み。 Safari(Mac)、IE10、は未確認です。

 

toDataURL()を利用する記事は「デモ2」に有ります。繁雑なのでお勧めしません。


Chrome Firefox Safari(Win) IE9、で動作確認済み。 Safari(Mac)、IE10、は未確認です。


 

HTML JS CSS


使用するライブラリ

easeljs preloadjs tweenjs

配布元 : CreateJS createjs.com


ライブラリの読み込み

ダウンロードしたJSを使用する場合。記述は一例です。(バージョン 0.7.0 使用)


<script type="text/javascript" src="js/easeljs-0.7.0.min.js"></script>
<script type="text/javascript" src="js/tweenjs-0.5.0.min.js"></script>

重要、バージョン違いでは動かない場合がありますので必ず合わせて下さい。


HTML (HTML5)


<div id="demo-wrap">
	<div id="image-box" class="radius"><canvas id="mainCanvas" width="640" height="300"></canvas></div>
</div>

JS

createJS035.js、JS名は任意に変更可。toDataURL()を利用しない方法に変更しました、簡単です。(20013/10/02)


//日本語
//createJS035.js
//トリミング

//------------------------------------------------------
//初期設定

//canvasの大きさ/全てこの値を使用
var canvasWidth=640;
var canvasHeight=300;

//------------------------------------------------------

//ステージ
var stage;
//コンテナ
var container,backcontainer;
//画像インスタンス
var sliceImage;
var sliceImage2;

//shadowフィルター
var shadow=new createjs.Shadow("#000000",0,0,4);

//ステージ周りセット
function init() {

	//STAGE
	stage=new createjs.Stage('mainCanvas');

	//最下位色背景層、無くとも良い
	var backrect=new createjs.Shape();
	backrect.graphics.beginFill("#000000").drawRect(0,0,canvasWidth,canvasHeight);
	stage.addChild(backrect);

	backcontainer=new createjs.Container();
	backImage=new createjs.Bitmap("/main/images/sky_back2.jpg");//640x300
	backcontainer.addChild(backImage);
	stage.addChild(backcontainer);

	//画像層、空コンテナを作る
	container=new createjs.Container();
	stage.addChild(container);

	stage.update();

	//GOTO-MAIN
	main();
}

//MAIN
function main() {

	//調整
	setTimeout(function() {

		//簡易1 drawImage()でトリミングBitmap()で表示 一般的
		slice_draw();

		//簡易2 drawImage()でトリミングShape()で表示 一般的ではない
		slice_draw2();

	},1000);

	//Ticker設定
	createjs.Ticker.setFPS(30);
	createjs.Ticker.addEventListener('tick',tick);
}

//DRAWアニメ1
function slice_draw() {

	//トリミングデータと画像URL
	var chip_pos_X=100;
	var chip_pos_Y=50;
	var chip_W=250;
	var chip_H=200;
	var img_url="/main/images/toyota_car10.jpg";//640x300

	var img=new Image();

	//完全に画像をロードしてから処理
	img.onload=function(){

		//画像分割貼り付け用の新規canvas
		var sliceCanvas=document.createElement("canvas");
		//大きさ重要
		sliceCanvas.setAttribute("width",chip_W);
		sliceCanvas.setAttribute("height",chip_H);
		//画像流し込み用のcontext参照
		var context=sliceCanvas.getContext("2d");
		//トリミングしてcontext貼り付け
		context.drawImage(img,chip_pos_X,chip_pos_Y,chip_W,chip_H,0,0,chip_W,chip_H);
		//Bitmap化、位置調整、addする
		sliceImage=new createjs.Bitmap(sliceCanvas);
		sliceImage.x=50;
		sliceImage.y=50;
		container.addChild(sliceImage);
		//shadowフィルター
		sliceImage.shadow=shadow;
		//透明度 0
		sliceImage.alpha=0;
		//Tween
		imageTween(sliceImage);

	};
	img.src=img_url;

}

//DRAWアニメ2
function slice_draw2() {

	//トリミングデータと画像URL
	var chip_pos_X=280;
	var chip_pos_Y=50;
	var chip_W=250;
	var chip_H=200;
	var img_url="/main/images/toyota_car11.jpg";//640x300

	var img=new Image();

	//完全に画像をロードしてから処理
	img.onload=function(){

		//画像分割貼り付け用の新規canvas
		var sliceCanvas=document.createElement("canvas");
		//大きさ重要
		sliceCanvas.setAttribute("width",chip_W);
		sliceCanvas.setAttribute("height",chip_H);
		//画像流し込み用のcontext参照
		var context=sliceCanvas.getContext("2d");
		//トリミングしてcontext貼り付け
		context.drawImage(img,chip_pos_X,chip_pos_Y,chip_W,chip_H,0,0,chip_W,chip_H);

		//Shape化、位置調整、addする
		sliceImage2=new createjs.Shape();
		sliceImage2.graphics.s().beginBitmapFill(sliceCanvas);
		operaRoundRect(sliceImage2,0,0,chip_W,chip_H,20);

		sliceImage2.x=340;
		sliceImage2.y=50;
		container.addChild(sliceImage2);
		//shadowフィルター
		sliceImage2.shadow=shadow;
		//透明度 0
		sliceImage2.alpha=0;
		//Tween
		imageTween(sliceImage2);

	};
	img.src=img_url;

}

//Tween
function imageTween(item) {

	//Tween フエード
	var tween=createjs.Tween.get(item)
	.to({alpha:1},2000);

}

//tick
function tick() {
	stage.update();
}

//quadraticCurveTo、こちら使用
function operaRoundRect(s,x,y,w,h,r) {
	s.graphics.moveTo(x+r,y)
	.lineTo(x+w-r,y)
	.quadraticCurveTo(x+w,y,x+w,y+r)
	.lineTo(x+w,y+h-r)
	.quadraticCurveTo(x+w,y+h,x+w-r,y+h)
	.lineTo(x+r,y+h)
	.quadraticCurveTo(x,y+h,x,y+h-r)
	.lineTo(x,y+r)
	.quadraticCurveTo(x,y,x+r,y);
}

//START
init();

注釈文を削除すれば、幾分早くなります。
(画像使用の場合は、登録画像パスは当方の記述ですから使用の際は環境に合わせてください)


CSS

createJS035.css、CSS名は任意に変更可


/*日本語 createJS035.css*/

#demo-wrap {
text-align:center;
}

#image-box {
position:relative;
top:0;left:0;
width:640px;
height:300px;
margin:0 auto;
padding:0;
box-shadow:0 0 10px #000;
-moz-box-shadow:0 0 10px #000;
-webkit-box-shadow:0 0 10px #000;
-o-box-shadow:0 0 10px #000;
-ms-box-shadow:0 0 10px #000;
background-color:#FFFFFF;
}

#image-box #mainCanvas {
border-radius:10px;
}
canvas {
border-style:none;
background-color:transparent;
}

.radius {
border-radius:10px;
-moz-border-radius:10px;
-webkit-border-radius:10px;
-o-box-border-radius:10px;
-ms-border-radius:10px;
}

当方のサンプルの例です。


簡単な説明


画像のトリミング

drawImage()で画像を指定範囲を指定の大きさに切り取り、Bitmap化して表示する例です。以前はtoDataURL()を利用していましたが、toDataURL()を使用しない方法が見つかりましたので記事を書き換えます。簡単になりました。
toDataURL()を利用する記事は「デモ2」に有ります。


【注意】画像を色々と処理する場合は、「画像が完全にロードされている」事が条件です。画像がロードされていない場合はブラウザによっては「重大なエラー」になる事も有ります。


下記は、デモの画像トリミング処理部分のコードです。これに沿って説明します。
トリミングする場合、「画像が完全にロードしている」ことが条件ですから、ここでは img.onload=function(){} を使用してみます。別の方法で画像をロードした場合にdrawImage()の「画像オブジェクト」部分の引数が違ってくる事も有ります。


例1、slice_draw()


var sliceImage;

//DRAWアニメ1
function slice_draw() {

	//トリミングデータと画像URL
	var chip_pos_X=100;
	var chip_pos_Y=50;
	var chip_W=250;
	var chip_H=200;
	var img_url="/main/images/toyota_car10.jpg";//640x300

	var img=new Image();

	//完全に画像をロードしてから処理
	img.onload=function(){

		//画像分割貼り付け用の新規canvas
		var sliceCanvas=document.createElement("canvas");
		//大きさ重要
		sliceCanvas.setAttribute("width",chip_W);
		sliceCanvas.setAttribute("height",chip_H);
		//画像流し込み用のcontext参照
		var context=sliceCanvas.getContext("2d");
		//トリミングしてcontext貼り付け
		context.drawImage(img,chip_pos_X,chip_pos_Y,chip_W,chip_H,0,0,chip_W,chip_H);
		//Bitmap化、位置調整、addする
		sliceImage=new createjs.Bitmap(sliceCanvas);
		sliceImage.x=50;
		sliceImage.y=50;
		container.addChild(sliceImage);
		//shadowフィルター
		sliceImage.shadow=shadow;
		//透明度 0
		sliceImage.alpha=0;
		//Tween
		imageTween(sliceImage);

	};
	img.src=img_url;

}

[説明図]

 

Bitmap化以前のcanvas処理など


1. トリミング画像貼り付け用の新規 canvas を作る。sliceCanvas=document.createElement("canvas")
2. 大きさを設定する。setAttribute("width",幅の値) setAttribute("height",高さの値)
大変重要です、canvas要素の大きさを設定しないとシステムの初期値(300x200)が設定され思うような拡大縮小など出来なくなる、CSSで制御しないで、HTMLで設定ください。
3. 画像流し込み用の context 参照する。context=canvasインスタンス名.getContext("2d")
4. トリミングして context に貼り付ける。context.drawImage(中を略します)
5. Bitmap化、sliceImage=new createjs.Bitmap(sliceCanvas);


● drawImage()の対象画像

必ず読み込み完了の画像ですから、サンプルでは new Image()オブジェクトである img が入ります。
ローダー、LoadQueue() で読み込んだ場合は、ローダー画像読み込み完了より取得した、リザルト値 event.result になります。


drawImage(new Image()オブジェクト,.........)
drawImage(ローダー取得リザルト値,.........)

● Bitmap化


//画像分割貼り付け用の新規canvas
var sliceCanvas=document.createElement("canvas");
//大きさ重要
sliceCanvas.setAttribute("width",chip_W);
sliceCanvas.setAttribute("height",chip_H);
//画像流し込み用のcontext参照
var context=sliceCanvas.getContext("2d");
//トリミングしてcontext貼り付け
context.drawImage(img,chip_pos_X,chip_pos_Y,chip_W,chip_H,0,0,chip_W,chip_H);
//Bitmap化
sliceImage=new createjs.Bitmap(sliceCanvas);

非常に簡単です。但し正式なBitmap化ではない。


グラフイックで利用する

グラフイックで画像流し込む場合もそのまま利用できる。


//Shape化
sliceImage=new createjs.Shape();
sliceImage.graphics.s().beginBitmapFill(sliceCanvas).drawRect(0,0,chip_W,chip_H,20);

グラフイックで利用するにも、非常に簡単です。


toDataURL()を利用しない方法の注意点

toDataURL()を利用しない方法は、本来のCreateJSでの Bitmap画像処理方法では無く、単に偶然に過ぎません。
再加工などで、Bitmap.image などの処理は出来ませんので、ご注意ください。「デモ」の様な問題の起きない範囲で使用するには便利です。


正式のBitmap()は
sliceImage=new createjs.Bitmap('画像URL');
です
-------------------------------------------------

正式のBitmap()ではないので

//作ってadd
sliceImage=new createjs.Bitmap(sliceCanvas);
stage.addChild(sliceImage);

//中身の交換は出来ない
sliceImage.image=new createjs.Bitmap(別に作ったキャンバス).image;

ブラウザによっては処理するものもあるが、エラーになる

このような場合は、面倒でも、toDataURL()を利用して Bitmap画像sliceImage を作らねば成りません。
removeChild() addChild()を利用するなら問題はないが、単に表示可能であるだけで使用が限定されます。
面倒な、toDataURL()の利用法は「デモ2」に有りますので参照下さい。


● 階層用コンテナに収容する訳
階層用コンテナつまりレーヤーの代替として利用の場合が多いが、個人的に多用しています。強制するツモリは有りませんのでこれは自由です。


[怪奇! Bitmap食み出し事件の捜査図、toDataURL()を利用した場合食み出る]

1. 階層構造(大まかな重ね順)を常に一定にしておける。
2. コンテナに収容のインスタンスなどの削除が簡単になる。
3. デモの様にCSSで角丸処理した場合に、ステージ角丸部分で、中のBitmap画像の「角が食み出す」事があるが、コンテナに収容すると「何故か食み出さないでCSSが有効」と成る。何故なのだ?
(toDataURL()を利用した場合は食み出る、利用しない場合は食み出ない、条件が違えば食み出す事も在るかも知れないので、コンテナに収容の方が一応安心か?)
4. 階層用コンテナ毎に移動したり出来るので、ブロック毎の管理が楽だ。(但し、階層が深くなり少し重くなる欠点あり)


● Operaで角丸処理が壊れる

 

Operaのみ、CreateJSの角丸 drawRoundRect() 処理が機能しないために(Operaの解釈の相違で角丸描画が崩れる)、角丸処理には、Operaでも問題の出ない、quadraticCurveTo での独自の角丸を作る「operaRoundRect関数」を使用している。operaRoundRect(Shapeインスタンス,x,y,w,h,r)で使用する。



//Shape化角丸処理
sliceImage2=new createjs.Shape();
sliceImage2.graphics.s().beginBitmapFill(sliceCanvas);
operaRoundRect(sliceImage2,0,0,chip_W,chip_H,20);

画像を分割して表示

当然分割された画像要素(インスタンス)は複数になりますから、トリミングを複数回繰り返すことになります。方法は同じでループ処理するだけです。
ただ注意することは、画像を分割する時に画像の大きさを「整数値」にする事です。少数値では隙が出来たり画像の組み合わせがズレたりします。
画像分割、画像分割アニメに関しては、当方の下記記事を参照下さい。


次ぎのページ、画像分割アニメに関しての簡単なデモです。始めは此方の方が判り易いかも知れません。

【参照】当方の記事: CreateJS 画像を分割(複数)してBitmap処理、Tweenさせる処理を考える


使用画像

画像などは原則、使用者が目的に応じ用意します。640x300 画像3つ。




一応、完動しますが全てテストです。効率化のため、予告無くJSなど修正する場合がありますので了承下さい。
また、CreateJSの「仕様」もクルクル変わっていますので、バージョン違い等に充分注意下さい


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]