読者です 読者をやめる 読者になる 読者になる

試される大地から

furaiboが送る技術ブログ。プログラミングのTipsなど書いていきます。

画像一括ダウンロード用のChrome拡張を作成・公開した話


遅れましたが、あけましておめでとうございます。
furaiboです。


今回はChrome拡張を作成し、Chrome拡張をChrome Webストア上に公開したので、そのことについて書いていきたいと思います。今回作成した拡張のソースコードは以下の私のGitHubリポジトリ上で公開しています。

furaibo/BulkImagesFetcher · GitHub



今回作成したChrome拡張は以下のページからダウンロード可能(無料)です。


BulkImagesFetcher - Chrome ウェブストア






さて、今回作ったChrome拡張の名前は "BulkImagesFetcher" といいます(英語的に正しいネーミングなのかすこぶる不安です・・・)


この拡張により、Google Chromeブラウザで閲覧中のページ中にある画像をいっぺんにダウンロードすることが出来ます。2chまとめサイトやギャラリー中の画像をまとめて落とすのに使えます。


なぜこんな既存のものと丸かぶりで無駄な拡張を作ったのかというと、画像を保存しようとするときに、「右クリック→名前をつけて保存」とやるのがあまりにも面倒なので、こうしたプロセスを省力化出来ないかと思ったからです。できればプログラムを作るにしても面倒くさい操作はできるだけしたくなく、ブラウザ上で保存の操作が出来たほうが何かと都合が良いので、Chrome拡張の作成に踏み切りました。



Chrome拡張の作り方

Chrome拡張を作るには、HTML+CSS+JavaScript、さらにお好みで(というかほぼ必須)jQueryなど、フロントエンドではお馴染みの知識が必要です。また、拡張に関する情報を記述するためのマニフェストファイルにはJSON形式を使いますので、これについても知っている必要があります。


また、Chrome拡張を実装したい人はまず、公式のChrome developer toolsを入れましょう。

Chrome Apps & Extensions Developer Tool - Chrome ウェブストア



Chrome拡張のプロトタイプを作るための基礎知識として以下のページなどを参照してみるのが良いと思います。他にググってみるといろいろと情報が見つかります。


Chrome Extension を作って公開する - Qiita


Google Chrome拡張の作り方(その1:マニフェストファイル作成とパッケージ化): 小粋空間

Developer's Guide - Google Chrome



Chrome拡張の構成とマニフェストファイル

Chrome拡張は、ブラウザ左上に設置されたボタンをクリックされたときに表示されるpopup.html、裏での処理に使われるbackground.html、拡張に関するオプションを設定するためのoptions.htmlなどのHTMLで構成されます。HTMLの名称は必ずpopup.htmlなどでなければならないということはなく、任意の名称で構いません。また、HTMLのデザインに関しては通常と同様にCSS、動作はJavaScript(+jQuery)を使って実装します。


マニフェストファイルなどは以下のように記述します。
Chrome拡張の名称や、Chromeの設定画面上で見ることのできる記述、アイコン画像へのパス、
オプションページやバックグラウンドページの指定、アクセス可能なURLなどの設定ができます。

{
    "manifest_version": 2,
    "name": "BulkImagesFetcher",
    "version": "1.0",
    "description": "Chromeで表示中のWebページ内にある画像を取得できるChrome拡張です。",
    "browser_action": {
        "default_icon": "icon/icon64.png",
        "default_popup": "popup.html"
    },
    "icons": {
        "16": "icon/icon16.png",
        "32": "icon/icon32.png",
        "64": "icon/icon64.png",
        "128": "icon/icon128.png"
    },
    "options_page": "options.html",
    "content_scripts": [
        {
            "matches": [
                "http://*/",
                "https://*/"
            ],
            "js": [
                "js/jquery-2.1.3.min.js",
                "js/util.js",
                "js/popup.js"
            ]
        }
    ],
    "background": {
        "scripts": [
            "js/jquery-2.1.3.min.js",
            "js/util.js",
            "js/background.js"
        ]
    },
    "permissions": [
        "tabs",
        "http://*/",
        "https://*/"
    ]
}

Webページ中の画像を取得する方法

これが非常に悩みどころでした。Chrome拡張ではクロスドメイン制約はないので、WebページのHTMLを参照して正規表現などで画像URLを抜き出すことは簡単に出来たのですが、肝心のURLから画像をどうやって保存するかという問題に直面しました。


Chrome拡張でJavaScriptを使って画像を取得する方法には2つ考えられます。

  • バイナリ形式で画像データを受信し、データからファイルを作成、File System APIを使って保存する
  • Chrome上で内部的に画像URLを指すaタグを作成し、クリックイベントを発火させ、ファイルを保存する


他にもあるのかもしれませんが、JavaScriptについて詳しいわけではないので、これ以外の方法があればお知らせください。


今回のChrome拡張の実装においては後者のアプローチをとりました。その際に参考にしたページは以下になります。



最初は前者アプローチで画像をダウンロードしようとはしたのですが、ブラウザのセキュリティ上の理由で、File System APIを使ったファイル保存だと、AppDataという、通常では隠しフォルダとなっている、サンドボックス化された領域にしか保存できないという大きな制約があったため、この方式での実装を断念しました。


小難しい話になってしまいましたが、まとめると、Chrome拡張でのファイル保存はめんどくさく、ローカルに保存したくても相当の制約があるということです。


以下参照


javascriptからファイル保存ダイアログを出す - Qiita



画像サイズの取得

これも相当悩みました。既にロードされた画像ならば画像の幅・高さの取得はJavaScriptを使って簡単にできるのですが、ロードが終わっていない段階で画像の幅・高さを取得しようとすると、値が0になってしまうという問題がありました。この問題については、サイズ取得をロードが完了したときのイベントとして設定することで回避することが出来ました。


以下参照

[JavaScript] 画像のオリジナル サイズを取得する 最もシンプルな方法 - こじょらぼ




アイコンの取得

フリーなアイコンを探したところ、以下のサイトのものが気に入りました。みなさんも各自好きなものを探してみるといいと思います。

Free vector icons - SVG, PSD, PNG, EPS & Icon Font - Thousands of Free Icons





完成したChrome拡張

ソースコードは結構な長さなので、ここでは割愛します。もし興味があれば上記のGitHubリポジトリを覗いてみるといいかと思います。


見た目は以下のようになっています。

f:id:incodethx3932:20150112180600p:plain



まず、高さ・幅などのサイズでダウンロードする画像を絞り込みます(アイコンなどの小さな画像をダウンロード対象としないため)。そして、ダウンロード候補画像のところで、ダウンロード対象の画像は不透明の状態、対象でない画像はかなり薄い半透明の状態で表示されます。


ダウンロードをする・しないは画像をクリックすることで切り替えることが出来ます。こうしてダウンロード画像を絞り込んだら、ダウンロードボタンを押すことで対象となる画像すべてを一気にダウンロードします。


反省点としては、ダウンロードボタンをクリックした瞬間にダウンロードバーが怒涛のようにアニメーションするのでやや鬱陶しいことと、ダウンロードフォルダに多くの画像が一気に入ってしまうので、整理しづらいことでしょうか。これらについては後に改善するかもしれません。


それでは・・・