ゲレの工房

ゲーム好きの中の人が、自分が作りたいアプリを作る記録です

更新情報 : 透過していないJPGをCanvas上で透過し、おはララジェネレータで貼り付ける

おはララジェネレータの更新情報です。
おはララジェネレータは、主にFF14スクリーンショットに、有志が作成したロゴを貼り付けるためのジェネレータです。

サイトはこちら
おはララジェネレータ

ソースコードはこちらになります。
GitHub - gelehrtecrest/ohalala-ss-generator

さて、今までは透過PNGを貼り付けるジェネレータを想定していました。
今回は透過していないロゴ、例えばJPGで公開されているロゴを貼り付けることができるように改造しました。
実は未完成な部分もあるのですが、それについても書きたいと思います。

使い方

例えば、次のようなJPGロゴ

これは JPGで公開されたロゴです。

今回の仕様では、このように、背景が白であることを前提としてジェネレータを作成しました。
なので余談になりますが、クルザスのかまくらで、グループポーズを使って背景白にした自キャラもロゴにできます。
だからどうしたっという話ですね。雑コラには使えるかもしれませんが。

準備

今回は、諸事情により、URL直リンクを使用することができません。JPGファイルをローカルPCにダウンロードする必要があります。
上記のようにTwitterで公開されたロゴでは、ブラウザを右クリックするとダウンロードできます。

f:id:gelehrtecrest:20171214152749p:plain

ロゴファイルを設定

ロゴファイルを設定する場所を2箇所に増やしました。
一つは今まで通り、もう一つは今回追加した白を透過したいロゴ用です。
JPGロゴ用には「合成したいロゴ(白透過)」と書いてあります。

f:id:gelehrtecrest:20171214153005p:plain

選択肢の3つ目ですね。

あとは今まで通り

合成ボタンを押せばロゴの挿入ができます。

こんな感じです。
ちょっとロゴが薄くなってしまうという問題は生じますが、だいたい問題なくロゴが貼り付けられます。

どのように動いているか。

参考サイト

こちらのサイトを参考にしました。

Canvasで画像の白を透過にする | スターフィールド株式会社

仕組み

仕組みを簡単にいうと、RGBの暗さを比較し、その暗さが一番高い数値を透過度に反映しています。
参考サイトを見ていただいてもいいのですが、少し改造したのをここでは載せます。

function loadlogocanvas(url, flag){
	var image = new Image();
	image.onload = function() {
		$('#canvas').attr({
			'width': image.width,
			'height': image.height
		});
		var canvas = document.getElementById('canvas');
		var context = canvas.getContext('2d');
		context.drawImage(image, 0, 0);
		var imageData = context.getImageData(0, 0, context.canvas.width, context.canvas.height);
		var data = imageData.data;
		for (var i = 0; i < data.length; i += 4) {
			//各カラーチャンネルで、一番暗い値を取得
			var minLuminance = 255;
			if(data[i] < minLuminance)
				minLuminance = data[i];
			if(data[i + 1] < minLuminance)
				minLuminance = data[i + 1];
			if(data[i + 2] < minLuminance)
				minLuminance = data[i + 2];

			if(flag){
				//一番暗い値を、アルファチャンネルに反映(明るいところほど透明に)
				data[i + 3] = 255 - minLuminance;
			}
		}
		context.putImageData(imageData, 0, 0);
	};
	image.src = url;
}
|JavaScript|<

url で取得した画像を、idが"canvas"のcanvasに書き込みます。(おはララジェネレータではこのcanvasは非表示にしています。)
このcanvasで作成された画像をEaselJSで再度合成してロゴ貼り付けを行なっているのです。

** 課題
これは私がEaselJSの仕様を理解していない問題が大きいのですが、<b>直リンクの画像が使えない</b>問題が起きています。

ちょっと別のコードの部分を
>|JavaScript|
//画像のロード
//ローカル
if($('input[name=logo]:checked').val() === 'local'){
	if(logoImageData !== null) {
		var baseImg = new Image();
		var canvas = document.getElementById('canvas');
		baseImg.src = canvas.toDataURL();
		img = new createjs.Bitmap(baseImg);
	} else {
		img = null;
	}
} else { // URL
	var baseImg = new Image();
	baseImg.src = $('#logourl').val();
	img = new createjs.Bitmap(baseImg);
}

ローカルにあるロゴ画像の場合は、canvas.toDataURL(); で画像を取得しています。これは正常に動きます。
ただ、同じように外部サイトの画像を直リンクしてcanvasに書き込んだ場合、toDataURL()が動きません。
これはクロスドメイン対策がブラウザ側で行われているためです。要するに外部のサイトの画像をcanvasでいじった後、再度画像URLにしちゃダメよというセキュリティー的なエラーです。

当然といえば当然でしょうか。
もしかすると toDataURLを使わない方法も思いつくかもしれませんが、今回はすぐにはプログラムできそうになかったので断念しました。

終わりに

今後も改良を加えて行きたいとおもいます。主に自分が使いやすいように作っているわけですが。
ご要望などがありましたら、コメントなどをいただけると嬉しいです。

質問箱もあるよー
gelehrtecrestの質問箱です | Peing

今回はここまで、それでは。


スポンサーリンク