POPSブログ

CreateJS sourceRect 画像トリミング

296

  Category:  javascript2014/05/17 pops 

Bitmapクラスの sourceRect プロパティを利用した画像トリミングです。毎度お馴染み「パクリ記事」であります。
また、sourceRect を使用しない方法などをも考えて見ます。
easeljs-0.7.1 でのテストです。

 

CreateJS sourceRect 画像トリミング テスト

今まで判らなかったのですが、Bitmapクラスのプロパティ sourceRect を使用してもトリミングを行うことが出来ます。CreateJSに例がないので使用方法などわからずになっていました。うっかり見過ごしていたのかも知れない?

下記、出展記事を参考ください。詳しく解説なされています。


以前、検索しても出なかったが最近になってわかった。大変ありがとうございます。

【出展、参考】webdelog さんの記事: EaselJSで画像をトリミングして表示させる

 

また、sourceRectを使用しない方法などをも考えて見ます。


 

DEMO


CreateJS sourceRect 画像トリミングのデモ、(createJS080.js)

このページはHTML5では有りませんので、デモページでご覧ください。「IE7.8」ではご覧いただけません。
/// 注意、ブラウザ、マシン性能により描画品質などに大きな差が有ります事了承下さい ///



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


 

HTML JS CSS


使用するライブラリ

easeljs preloadjs tweenjs

配布元 : CreateJS createjs.com


ライブラリの読み込み

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


<script type="text/javascript" src="js/easeljs-0.7.1.min.js"></script>
<script type="text/javascript" src="js/preloadjs-0.4.1.min.js"></script>

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


HTML (HTML5)



<div id="demo-wrap">
	<div id="image-box">
		<canvas id="mainCanvas" width="800" height="500"></canvas>
	</div>
</div>

JS

createJS080.js、JS名は任意に変更可。注意、easeljs-0.7.1用です。


//日本語
//createJS080.js
//sourceRect画像トリミング

//------------------------------------------------------
//canvasの大きさ/全てこの値を使用
var canvasWidth=800;
var canvasHeight=500;

//画像manifestリスト
var manifest=[
{src:"/main/images/flight01.jpg",id:"PHOTO1"},
{src:"/main/images/flight02.jpg",id:"PHOTO2"},
{src:"/main/images/flight03.jpg",id:"PHOTO3"},
]

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

//ステージ
var stage;
//コンテナ

//ローダー
var loader;
//読み込み画像URL保存容器
var assets=[];

//陰影
var shadow=new createjs.Shadow("#000000",0,0,4);

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

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

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

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

	//Main-Ticker設定
	createjs.Ticker.setFPS(30);
	//createjs.Ticker.timingMode=createjs.Ticker.RAF;
	createjs.Ticker.addEventListener('tick',tick);

	//画像一括ロードに進む
	bulkload();

}

//bulk-load、画像一括ロード
function bulkload() {

	//Loader
	loader=new createjs.LoadQueue(false);
	//loader EventListener設定
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);
	//Manifestを使用、manifest読み込み開始
	loader.loadManifest(manifest);

}
//各画像読み込み完了
function fileload (eventObject) {

	//エラー無しの画像をassets容器に保存
	assets.push(eventObject.result);

}
//全ての画像読み込み完了
function complete (event) {

	//loader Listener削除 こちら使用に修正
	loader.removeEventListener("fileload",fileload);
	loader.removeEventListener("complete",complete);

	setTimeout(function() {

		main();

	},1000);

}

//MAIN
function main() {

	//----------------Bitmap---------------------------

	set_memo(50,15,"1. Bitmap sourceRect処理OK");
	//sourceRect処理
	var mainImage=new createjs.Bitmap(assets[0]);
	//X,Y,幅,高さ
	mainImage.sourceRect={x:100,y:100,width:200,height:200};
	//中心補正と表示位置
	mainImage.regX=200/2;
	mainImage.regY=200/2;
	mainImage.x=150;
	mainImage.y=130;
	//陰影
	mainImage.shadow=shadow;
	stage.addChild(mainImage);

	set_memo(300,15,"2. Bitmap エレメント処理OK");
	//drawImage処理トリミング画像エレメントを得る
	//X,Y,幅,高さ
	var elem_image=createImgTrimming(100,100,200,200,assets[1]);
	//エレメント画像をBitmap化
	var mainImage2=new createjs.Bitmap(elem_image);
	//中心補正と表示位置
	mainImage2.regX=200/2;
	mainImage2.regY=200/2;
	mainImage2.x=400;
	mainImage2.y=130;
	//陰影
	mainImage2.shadow=shadow;
	stage.addChild(mainImage2);

	set_memo(550,15,"3. Bitmap エレメント合成処理OK");
	//drawImage処理トリミング画像エレメントを得る
	//画像合成、画像1位置大きさ、画像2位置大きさ、合成位置
	var elem_image3=createMixedCanvas(100,100,200,200,assets[0],100,100,100,100,assets[1],50,50);
	//エレメント画像をBitmap化
	var mainImage3=new createjs.Bitmap(elem_image3);
	//中心補正と表示位置
	mainImage3.regX=200/2;
	mainImage3.regY=200/2;
	mainImage3.x=650;
	mainImage3.y=130;
	//陰影
	mainImage3.shadow=shadow;
	stage.addChild(mainImage3);

	//---------------Graphics-----------------------

	set_memo(50,255,"4. Shape Matrix処理ならOK / 陰影Chrome NG");

	//Matrix処理ならOK
	//Shape
	var mainShape=new createjs.Shape();
	//Matrix
	var matrix=new createjs.Matrix2D();
	matrix.translate(-100,-100);
	mainShape.graphics.beginBitmapFill(assets[0],"no-repeat",matrix).drawRoundRect(0,0,200,200,10);
	//中心補正と表示位置
	mainShape.regX=200/2;
	mainShape.regY=200/2;
	mainShape.x=150;
	mainShape.y=370;
	//陰影
	mainShape.shadow=shadow;
	stage.addChild(mainShape);

/*
	//sourceRect処理ならない
	var mainImage4=new createjs.Bitmap(assets[0]);
	//X,Y,幅,高さ
	mainImage4.sourceRect={x:100,y:100,width:200,height:200};
	//Shape
	var mainShape=new createjs.Shape();
	mainShape.graphics.beginBitmapFill(mainImage4.image).drawRoundRect(0,0,200,200,10);
	//中心補正と表示位置
	mainShape.regX=200/2;
	mainShape.regY=200/2;
	mainShape.x=150;
	mainShape.y=370;
	//陰影
	mainShape.shadow=shadow;
	stage.addChild(mainShape);
*/


	set_memo(300,255,"5. Shape エレメント処理OK / 陰影Chrome OK");
	//Shape2
	var mainShape2=new createjs.Shape();
	//drawImage処理トリミング画像エレメントを得る
	//X,Y,幅,高さ
	var elem_image=createImgTrimming(100,100,200,200,assets[1]);
	//エレメント挿入
	mainShape2.graphics.beginBitmapFill(elem_image).drawRoundRect(0,0,200,200,10);
	//中心補正と表示位置
	mainShape2.regX=200/2;
	mainShape2.regY=200/2;
	mainShape2.x=400;
	mainShape2.y=370;
	//陰影
	mainShape2.shadow=shadow;
	stage.addChild(mainShape2);

	set_memo(550,255,"6. Shape エレメント合成処理OK");
	//drawImage処理トリミング画像エレメントを得る
	//画像合成、画像1位置大きさ、画像2位置大きさ、合成位置
	var elem_image3=createMixedCanvas(100,100,200,200,assets[0],100,100,100,100,assets[1],50,50);
	//Shape3
	var mainShape3=new createjs.Shape();
	//エレメント挿入
	mainShape3.graphics.beginBitmapFill(elem_image3).drawRoundRect(0,0,200,200,10);
	//中心補正と表示位置
	mainShape3.regX=200/2;
	mainShape3.regY=200/2;
	mainShape3.x=650;
	mainShape3.y=370;
	//陰影
	mainShape3.shadow=shadow;
	stage.addChild(mainShape3);

}

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

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

//MEMOTEXT
function set_memo(x,y,t) {
	var text=new createjs.Text(t,"10px Arial","#FF0000");
	text.x=x;
	text.y=y;
	text.textBaseline="middle";
	stage.addChild(text);
}

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

//画像trimming
function createImgTrimming(x,y,w,h,img) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(img,x,y,w,h,0,0,w,h);

	return canvas;
}

//画像合成、位置、幅、高さ、画像1、画像2、合成位置
function createMixedCanvas(x,y,w,h,img,x2,y2,w2,h2,img2,x3,y3) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//合成
	ctx.drawImage(img,x,y,w,h,0,0,w,h);
	ctx.drawImage(img2,x2,y2,w2,h2,x3,y3,w2,h2);
	//
	return canvas;
}

//幅、高さ、画像
function createImgCanvas(w,h,patternimg) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(patternimg,0,0,w,h);

	return canvas;
}

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

//START
init();

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


CSS

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


/*日本語 createJS080.css*/

#demo-wrap {
position:relative;
width:auto;
height:100%;
text-align:center;
}

#image-box {
/*position:absolute;*/
position:relative;
top:0;left:0;
width:800px;
height:500px;
padding:0;
margin:0 auto;
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:#000000;
}

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


 

簡単な説明


[説明図]

 

CreateJSにトリミング関連のものがないので不思議に思っていましたが、あったのですね。見落としも甚だしい年頃であります。間違いキ違いは季節の変わり目には多いものです。
他の方法なども加えて記事にしてみます。


1. Bitmapクラスの sourceRect プロパティを利用した画像トリミング。
(内部処理でdrawImage()を使用はしています)
2. 直接「html5 Canvas処理」、drawImage()を利用する画像トリミング。
3. 画像の合成処理。


Bitmapクラスの処理

Bitmapクラス処理では、中に入れる画像データの描く範囲が描画されますので、画像の「XY位置」および「大きさ」が重要になります。


Bitmapクラスの sourceRect プロパティを利用した画像トリミング

サンプル1


sourceRectは詳しい説明もなく使用例がないので判らないでいましたが、次の様にすれば良い訳です。
Bitmapインスタンスに対して sourceRect プロパティを設定すれば良いだけです。


下記デモ例、assets[0]などは、読み込み完了画像result値です。


書式


Bitmapインスタンス.sourceRect=Rectangle;
つまり
Bitmapインスタンス.sourceRect={x:X位置,y:Y位置,width:画像幅,height:画像高さ};

------------------------------------------------------------------------------

Rectangle ( [x=0] [y=0] [width=0] [height=0] )


//sourceRect処理
var mainImage=new createjs.Bitmap(assets[0]);
//X,Y,幅,高さ
mainImage.sourceRect={x:100,y:100,width:200,height:200};
//中心補正と表示位置
mainImage.regX=200/2;
mainImage.regY=200/2;
mainImage.x=150;
mainImage.y=130;
//陰影
mainImage.shadow=shadow;
stage.addChild(mainImage);

webdelog さんの記事の「パクリ」ですから処理は同じです。
Bitmapに画像を入れてから、その後に大きさを変更させてBitmap画像を更新させる方法なので、予感としてであるが制約がでる可能性がある。

トリミングの位置、大きさなどは「画像の範囲内」で指定ください、画像範囲を超えると、ブラウザによっては「重大なエラー」になりますので注意が必要です。


以上、「Bitmapクラスの sourceRect プロパティを利用した画像トリミング」、でした。
下記は、そのほかの処理方法です。


 

直接「html5 Canvas処理」drawImage()を利用する画像トリミング

サンプル2


sourceRect プロパティを利用を知らないために以下の様に、BitmapでCanvasエレメントを表示できますから、CanvasエレメントでdrawImage()を利用して画像トリミング。その後Bitmapに代入して表示していました。
また、CanvasエレメントはGraphicsクラスのbeginBitmapFillで利用出来るのも便利です。


書式


Bitmapインスタンス=new createjs.Bitmap(Canvasエレメント);

独自の、createImgTrimming()関数を作り利用します。私個人としてはこちらの方が使い易いのですが....


//drawImage処理トリミング画像エレメントを得る
//X,Y,幅,高さ
var elem_image=createImgTrimming(100,100,200,200,assets[1]);
//エレメント画像をBitmap化
var mainImage2=new createjs.Bitmap(elem_image);
//中心補正と表示位
mainImage2.regX=200/2;
mainImage2.regY=200/2;
mainImage2.x=400;
mainImage2.y=130;
//陰影
mainImage2.shadow=shadow;
stage.addChild(mainImage2);

------------------------------------------------------------------------------

//画像trimming
function createImgTrimming(x,y,w,h,img) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(img,x,y,w,h,0,0,w,h);

	return canvas;
}

● 参考、サムネールなどを作る場合

サムネールなどを作る場合は、下記関数を利用すれば、縮小のサムネール画像を得られる。(当然品質は良くないが拡大も可能である)
patternimgは、画像、Canvasエレメントなどである。原則、画像はdrawImage()処理すれば良い。


//幅、高さ、画像
function createImgCanvas(w,h,patternimg) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(patternimg,0,0,w,h);

	return canvas;
}

Canvasエレメントを作り、画像取り込み加工、テキスト、図形など描けば、画像同様のものが出来、表示するにはBitmap()に取り込めばよいので重宝である。


画像の合成処理

サンプル3


直接「html5 Canvas処理」drawImage()を繰り返すことにより、一枚の画像に小さな画像などを合成出来ますので、以下の様に処理しました。
直接Canvas処理ですから、勿論、画像以外のものも合成できる利点があります。いささか面倒にはなりますが...


適当に独自の関数を作り処理します、表示には、Bitmapクラスを利用すれば良い訳です。


//drawImage処理トリミング画像エレメントを得る
//画像合成、画像1位置大きさ、画像2位置大きさ、合成位置
var elem_image3=createMixedCanvas(100,100,200,200,assets[0],100,100,100,100,assets[1],50,50);
//エレメント画像をBitmap化
var mainImage3=new createjs.Bitmap(elem_image3);
//中心補正と表示位置
mainImage3.regX=200/2;
mainImage3.regY=200/2;
mainImage3.x=650;
mainImage3.y=130;
//陰影
mainImage3.shadow=shadow;
stage.addChild(mainImage3);

------------------------------------------------------------------------------

//画像合成、位置、幅、高さ、画像1、画像2、合成位置
function createMixedCanvas(x,y,w,h,img,x2,y2,w2,h2,img2,x3,y3) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//合成
	ctx.drawImage(img,x,y,w,h,0,0,w,h);
	ctx.drawImage(img2,x2,y2,w2,h2,x3,y3,w2,h2);
	//
	return canvas;
}

特殊な処理ですが、必要な時もあるかも知れません?..........




 

ShapeクラスのGraphics処理

Graphics処理ではGraphicsの描く範囲を超えた部分の画像は描画されませんので、画像の「XY位置」が重要になります。一応Canvasエレメントでトリミングしてから利用します。

[注意]、以前OperaのRoundRectに不具合がありましたが、現在OperaはChromeエンジンに切り替わりましたので、角丸は通常のdrawRoundRectで描画しています。


Graphicsクラスでの画像流し込み

GraphicsクラスのbeginBitmapFillで利用するには、Canvasエレメントで画像を加工してから利用するのが便利です。


1. sourceRect プロパティを利用した画像流し込みは出来ません。(出来る方法があるかは不明)
2. Graphicsクラスでの画像トリミングなどはMatrix処理すれば良いのですが、陰影処理するとChrome(およびChromeエンジンのOpera)でNGになります(下図参照)。但し、Canvasエレメントで画像を加工してから利用するとNGにはなりません。(この辺の事情は、ワタシには不明)
3. Graphicsクラスでの合成画像処理もOKです。


● GraphicsクラスのbeginBitmapFillで利用


Shapeクラスインスタンス=new createjs.Shape();
Shapeクラスインスタンス.graphics.beginBitmapFill(Canvasエレメント)....

------------------------------------------------------------------------------

Graphicsクラスインスタンス.beginBitmapFill(Canvasエレメント)....

sourceRectが機能しない例

通常、beginBitmapFill()に「Bitmapインスタンス.image」を下の様に挿入できるが、sourceRect処理する下の例はならない。(sourceRect、x:100,y:100が機能しない)


//sourceRect処理
var mainImage4=new createjs.Bitmap(assets[0]);
//X,Y,幅,高さ
mainImage4.sourceRect={x:100,y:100,width:200,height:200};
//Shape
var mainShape=new createjs.Shape();
//Bitmapインスタンス.imageは表示はするがsourceRectが機能しない
mainShape.graphics.beginBitmapFill(mainImage4.image).drawRect(0,0,200,200);

BitmapにsourceRect処理しても「Bitmapインスタンス.image」には変化はないので、beginBitmapFill()には代入できない。


 

[ Matrix処理で壊れる図解 ]

 

GraphicsクラスはsourceRectでのトリミングは出来ませんので、Matrix処理します、但し、Shape()に直接陰影処理すると、Chromeで、右および下方の陰影がこわれます。(上図参照)
Shape()の下に別途Shape()を配置して陰影をつければOKですが、コンテナに収容しなければなりませんし大変です。
Matrix処理ではなく、Canvasエレメントで画像を加工してから利用すると陰影は正常です。
(陰影の不具合はChromeに問題があるようです、今後、直るかなどは不明)


Graphicsクラスで、Matrix処理して利用する

サンプル4



//Matrix処理ならOK
//Shape
var mainShape=new createjs.Shape();
//Matrix
var matrix=new createjs.Matrix2D();
matrix.translate(-100,-100);
mainShape.graphics.beginBitmapFill(assets[0],"no-repeat",matrix).drawRoundRect(0,0,200,200,10);
//中心補正と表示位置
mainShape.regX=200/2;
mainShape.regY=200/2;
mainShape.x=150;
mainShape.y=370;
//陰影
mainShape.shadow=shadow;
stage.addChild(mainShape);

陰影なしなら問題はない、陰影を付けたいなら、次の様にすると正常になります。


GraphicsクラスでCanvasエレメントで画像を加工してから利用する

サンプル5



//Shape2
var mainShape2=new createjs.Shape();
//drawImage処理トリミング画像エレメントを得る
//X,Y,幅,高さ
var elem_image=createImgTrimming(100,100,200,200,assets[1]);
//エレメント挿入
mainShape2.graphics.beginBitmapFill(elem_image).drawRoundRect(0,0,200,200,10);
//中心補正と表示位置
mainShape2.regX=200/2;
mainShape2.regY=200/2;
mainShape2.x=400;
mainShape2.y=370;
//陰影
mainShape2.shadow=shadow;
stage.addChild(mainShape2);

------------------------------------------------------------------------------

//画像trimming
function createImgTrimming(x,y,w,h,img) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(img,x,y,w,h,0,0,w,h);

	return canvas;
}

Matrix処理しない。(テストで判ったことで、理由などはワタシは不明)
画像であるから、drawImage()処理をするが、目的に応じて、処理の関数を作って利用すれば多様性に富む細やかな処理が可能である。最近ワタシはこの手法での処理が多くなっている。beginBitmapFill()への代入のみならず、Bitmap()にも直接代入出来るのでより便利と思う。


Graphicsクラスでの画像合成処理

サンプル6


beginBitmapFill()に直接、Canvasエレメントを入れることができます。処理は上記、Bitmap()の場合と同じです。


//drawImage処理トリミング画像エレメントを得る
//画像合成、画像1位置大きさ、画像2位置大きさ、合成位置
var elem_image3=createMixedCanvas(100,100,200,200,assets[0],100,100,100,100,assets[1],50,50);
//Shape3
var mainShape3=new createjs.Shape();
//エレメント挿入
mainShape3.graphics.beginBitmapFill(elem_image3).drawRoundRect(0,0,200,200,10);
//中心補正と表示位置
mainShape3.regX=200/2;
mainShape3.regY=200/2;
mainShape3.x=650;
mainShape3.y=370;
//陰影
mainShape3.shadow=shadow;
stage.addChild(mainShape3);

------------------------------------------------------------------------------

//画像合成、位置、幅、高さ、画像1、画像2、合成位置
function createMixedCanvas(x,y,w,h,img,x2,y2,w2,h2,img2,x3,y3) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//合成
	ctx.drawImage(img,x,y,w,h,0,0,w,h);
	ctx.drawImage(img2,x2,y2,w2,h2,x3,y3,w2,h2);
	//
	return canvas;
}

特殊な処理ですが、必要な時もあるかも知れません?..........
実際に、前ページのキャプチャー画像の合成で利用している。結果は良好である。


以上は現時点での問題であり、今後のCreateJS、ブラウザの進歩、などにより変わるかなどは一切不明です。


使用画像

原則、画像は使用者が用意します。640x300 使用画像はデモページにあります。


トリミングについては、以下のページも参照ください。

【参照】当方の記事: CreateJS 画像をトリミング(又は分割)してBitmap処理、Tweenさせる処理を考える


Graphicsクラスでの画像と陰影との不具合は下記記事参照ください。(最近のOperaは、不具合が解消されました)

【参照】当方の記事: CreateJS Chromeでの shadowフィルター と、Opera での drawRoundRect の不具合の修正



一応、完動しますが全てテストです。効率化のため、予告無くJSなど修正する場合がありますので了承下さい。

CreateJSは結構「仕様」が変わりますので特に注意が必要です。


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧



[1]