2016

8

25

Chrome Extension(拡張機能)開発してやんよ!!!

スポンサードリンク


Chromeブラウザの拡張機能(Chrome Extension)をご存知でしょうか?
Chromeブラウザに入れてあんなこともこんなこともできるし・・・って優れモノ
なんでもHTMLとJavaScriptで作れてしまうという事を聞いたので早速作ってみました。

せっかくなのでChromeウェブストアに公開しましたので使ってみてください。
Chromeウェブストア紹介ページ

今回作成した拡張機能アイテムの紹介

アイテム名『簡易リサイズしてやんよ!!!』

アイコンをクリックしてポップアップに画像ファイルをドラッグ&ドロップをすると、指定サイズ(ピクセル値)にリサイズされ再生成されます。

プレビュー生成された画像ファイルはドラッグ&ドロップでデスクトップにコピー、または右クリックから保存してください。

PhotoShopなどの画像編集ツールを起動させることなく、簡易的に画像のリサイズが行えます。


※変な不信感を持たれないために下記にスクリプトコードを公開していますが、
ドロップした画像ファイルはどこかの怪しいサーバーにアップロードされてしまうといった事や、
生成されたリサイズ画像がユーザーの意図しない場所で保存されるといった事はありませんのでご心配なく。


作成手順と必要なファイル

この拡張機能は本当にシンプルなリサイズ機能のみの拡張機能ですので必要なファイルも最低限のファイルです。
適当な名前で新規フォルダを作成し、その中に以下のファイルを用意してください。

『manifest.json』

公開ページやChromeの管理画面でこのアイテムの紹介や仕様を明記するための必須ファイルです

『icon_32.png』『icon_48.png』『icon_128.png』

インストールするとブラウザ右上や管理画面に表示するためのアイコン画像です。
サイズは32×32、48×48、128×128の3種類(16×16もあれば)くらいあれば大丈夫だったと思います。
※画像アイコンはなくても大丈夫ですが、何の拡張機能かわかりやすいようにあった方が良いと思います。

『popup.html』

ブラウザ右上に表示されるアイコンをクリックするとポップアップ表示される拡張機能のコンパネ用ファイルです。

『style.css』

『popup.html』の装飾用CSS

『background.js』

『popup.html』で動作するスクリプトファイル

『jquery-1.8.2.min.js』

『background.js』でjQueryメソッドを使用しているためjQueryのライブラリファイル
※バージョンの指定は特にありませんが、古すぎても新しすぎても動作するかわかりません。


手順1 『manifest.json』ファイルの準備

マニュフェスト(宣言・声明書を意味する)、スマホアプリなどを作成した事のある方にはおなじみですが、Googleに申請するための申請書兼、Chromeブラウザにインストールさせるための仕様書の役割を果たします。
{
  "name": "簡易リサイズしてやんよ!!!",
  "version": "0.1.0",
  "manifest_version": 2,
  "description": "指定サイズにリサイズして画像を再生成します",
  "icons": {
	"32": "icon_32.png",
	"48": "icon_48.png",
	"128": "icon_128.png"
  }, 
  "browser_action": {
    "default_popup": "popup.html"
  },
  "background": {
	"css": ["style.css"],
    "scripts": [
		"jquery-1.8.2.min.js",
		"background.js"
    ]
  }
}

name

拡張機能の名前を付けてください。最大45文字までです。

version

メジャー・マイナーともに、拡張機能を更新する際には必ずバージョンが上げてください。

manifest_version

マニフェストファイル自身のバージョンです。
現在のバージョンは ”2” で、なおかつ現在有効なバージョンは 2 しかありません。

description

拡張機能の説明文です。最大132文字までです。

icons

アイコン画像を用意した種類の分だけ、サイズ:ファイル名の項目を追加してください。
※アイコン画像を入れない場合はこの項目は削除してください。

browser_action

こちらは、「browser_action」と「page_action」の2種類からいづれかのタイプを選択しますが、今回作成した拡張機能は「browser_action」を選択して、そこに連動させる「popup.html」を指定しています。

browser_action」 ・・・ ほぼ全てのページに対して、またはページに依存せず拡張機能を使用したい場合に選択します。
page_action」 ・・・ 特定のページを開いたときのみ、URL欄の横にアイコンが表示されます。条件に一致しないページでは、アイコンが非表示になります。

background

アイコンをクリックした際にポップアップの役割を果たすバックグラウンドページの設定です。
このファイルに関連付けられているCSSやJSファイルを明記します。

このほかにも拡張機能に実装する機能によってはマニュフェストに記述する項目は増えます。
例えば特定のURLを開いた場合にのみ動作するスクリプトファイルが必要な場合は「content_scripts
バックグラウンドページと実際のブラウザ間でのデータのやり取りを行う場合は「permissions」など


手順2 『popup.html』ファイルの準備

通称バックグラウンドページ(またはイベントページ)と呼ばれます。
こちらにリサイズするサイズ指定するフォームとリサイズ元となる画像をドラッグ&ドロップするエリアを作成します。
※このポップアップで指定した装飾は実際に見ているページにも影響してしまうため、干渉してしまわないようにbodyにまず付けられないであろうID名をつけてCSSファイルにも指定してください。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css" type="text/css">
<script src='jquery-1.8.2.min.js'></script>
<script src='background.js'></script>
</head>
<body id="chromeApp" style="min-width:200px">
<div id="imageSlice">
    <div id="imageSheetBox">
        <p>横幅:<input id="sliceSize" min="1" max="9999" value="500" step="1" type="number">px<br>(1px~9999pxの範囲で設定)</p>
        <div id="resizeZone">リサイズしたい画像を<br>ドロップしてください<br></div>
        <div id="resizeSliceBox"></div>
    </div>
</div>
</body>
</html>

手順3 『style.css』ファイルの準備

『popup.html』同様にh1タグだけで指定とかするとブラウザで観ているページへも干渉してしまう場合があるので、
bodyに特有のID名を付けてこちらを指定した上で各要素のプロパティを指定してください。
@charset "utf-8";
/* =========================================================
 リセット
========================================================= */
* {
	margin: 0;
	padding: 0;
}
/* =========================================================
 clearfix
========================================================= */
#chromeApp .clearfix:after {
	content: "";
	clear: both;
	display: block;
}

#chromeApp {
	font-family: 'メイリオ', Meiryo, 'ヒラギノ角ゴ ProN', 'Hiragino Kaku Gothic ProN', sans-serif;
	overflow: scroll;
}
#chromeApp a:hover {
	text-decoration: none;
	opacity: 0.8;
}
/* =========================================================
 詳細な装飾
========================================================= */
/*	簡易スライス	*/
#chromeApp #imageSlice h1 {
    font-size: 130%;
    margin: 10px auto;
    width: 96%;
}
#chromeApp #imageSheetBox {
	display: block;
}

#chromeApp #imageSlice #resizeZone {
	display: block;
    border: 2px dashed #bbb;
    border-radius: 5px;
    color: #bbb;
    padding: 25px;
    text-align: center;
	margin: 10px auto 5px;
	font-size: 12px;
	-khtml-user-drag: element;
}

#chromeApp #imageSlice #slice {
    width: 100%;
    height: 30px;
    line-height: 20px;
    text-align: center;
    margin: 10px auto;
    display: block;
    cursor: pointer;
    background: #CCC;
    border-radius: 5px;
    font-weight: bold;
    font-family: 'メイリオ', Meiryo, 'ヒラギノ角ゴ ProN', 'Hiragino Kaku Gothic ProN', sans-serif;
}
#chromeApp #imageSlice #resizeSliceBox img{
	width: 100%;
	display: block;
}

手順4 『background.js』ファイルの準備

バックグラウンドページでの挙動処理を記述します。
FileAPIをつかってドラッグ&ドロップされたファイルを判定し、画像ファイルならば
サイズ指定された横幅サイズ(縦は横幅の画角に合わせて自動判定)に変更して
canvasを使ってプレビュー領域となる要素へ描画します。
(function() {
$(function(){
	/**************************************************************************
		簡易リサイズ機能
	**************************************************************************/
	
	//ローカル画像ファイルをブラウザに投影
	function handleFileSlice(evt) {
		$('#resizeSliceBox img').remove();
		evt.stopPropagation();
		evt.preventDefault();
		var files = evt.dataTransfer.files;
		var output = [];
		for (var i = 0, f; f = files[i]; i++) {
			console.log(files[i]);
			
			//ファイルの形式を確認
			if (!f.type.match('image.*')) {
				alert("このファイルは画像ファイルではありません");
				continue;
			}
	
			var file = f;
			var canvas = document.createElement("canvas"),
			ctx = canvas.getContext('2d'),
			image = new Image();
			canvas.width = canvas.height = 0;
			image.src = URL.createObjectURL(file);
			image.onload = function() {
				var sliceSize = $('#sliceSize').val();
				if(sliceSize == 0){
					//元サイズのまま
					var w = image.naturalWidth;
					var h = image.height * (image.naturalWidth/image.width);
				}else{
					//横幅に合わせてリサイズ
					var w = sliceSize;
					var h = Math.round(sliceSize / image.naturalWidth * image.naturalHeight);
				}
				console.log(w + "+" + h);
				canvas.width = w;
				canvas.height = h;
				ctx.drawImage(image, 0, 0, w, h);
				
				var img = document.createElement('img');
				img.src = canvas.toDataURL(file.type);
				var head = 'data:' + file.type + ';base64,';
				var imgFileSize = Math.round((img.src.length - head.length)*3/4);
				var fileSlice = image.naturalWidth + "px ⇒ " + sliceSize + "px";
				
				$("#resizeSliceBox").append(img);
				$('#resizeZone').html('<span style="color:blue">リサイズ処理しました(' + fileSlice + ')<br>デスクトップにコピーしてください</span>');
			}
		};
		
		
	};
									   
	
	//画像ファイルのドラッグ&ドロップ設定
	function handleDragOver(evt) {
		evt.stopPropagation();
		evt.preventDefault();
		evt.dataTransfer.dropEffect = 'copy';
	};
	var resizeZone = document.getElementById('resizeZone');
	resizeZone.addEventListener('dragover', handleDragOver, false);
	resizeZone.addEventListener('drop', handleFileSlice, false);		
	resizeZone.addEventListener('dragenter', handleDragOver, false);
	
/**********************************************************************/		
});
}) ();


作成したフォルダをブラウザに実装

上記ファイルを準備したフォルダを実際にChromeブラウザに実装してみます。
  • ・ブラウザ右上の設定アイコン → 「設定」
  • ・新規タブで設定ページがでますので、画面左上の「拡張機能」を選択
  • ・「拡張機能」項目の画面右上の「デベロッパーモード」にチェック
  • 『パッケージ化されていない拡張機能を読み込む…』をクリックして作成したフォルダを選択
  • ※『manifest.json』に足りない項目やファイル名に違いがあった場合はエラーになるため内容を確認してください。

これでインストール完了です。
Chromeブラウザの右上に作成した拡張機能のアイコン画像(画像がない場合は拡張機能の名前の最初の一文字目)が表示されます。
リサイズする画像サイズが大き過ぎる場合、canvas生成するまで多少時間がかかります

現在、Chromeウェブストアに公開していない拡張機能はブラウザの再起動時に「不明な拡張機能を削除しかすか?」の確認アラートが出ますので、インストール後も使い続ける場合は毎回「キャンセル」を選択してください。
※「削除」を選択した場合は拡張機能が無効になってしまうため、再度インストールしてください


まとめ

『manifest.json』の仕様などについては色々手探りしながらの体験となりましたが、本当にHTMLとJavaScript(正確にはcanvasとFileAPIも併用)で作れてしまいました!

ほかのブラウザでもアドオンなどは作れますが、Firefoxアドオンなどは素人ではかなりハードル高めですが、WEBサイトを作るのと同じ要領で作れてしまう(作れる様に設計してくれている)Googleの技術力に改めて感銘を受けました。

みなさんも是非、仕事効率化などのアイディアを思いついたら開発してみてください。


トップへ