Creazy!

WEBエンジニア・ヤガーのテック・ガジェットブログ

技術情報

PHP + Mac + Bookmarklet でスクリーンキャプチャしてサムネイルとか

投稿日:


ターミナルを立ち上げて、おもむろに「screencapture test.png」と入力してreturnキーを押下すると画面全体のキャプチャ画像が「test.png」として保存されることになります(PNG形式)。

via: ウノウラボ Unoh Labs: Macでのスクリーンショットの撮り方まとめ

「Command+Shift+3」でスクリーンキャプチャが取れるのは知ってたんだけど、screencapture っていうマンマなコマンドが存在しているのは知りませんでした。
で、コマンドでキャプチャ取れるんならPHPからexecでコマンド実行してWEBページのサムネイル作ったりできるんじゃないか…とか思い付いてしまった。
PHP + Windowsとかなら結構簡単にできちゃうんだよなぁ。
PHP+Windowsでスクリーンショットやサムネイル作成 – Do You PHP はてな
秋元@サイボウズラボ・プログラマー・ブログ: PHP+Windowsでスクリーンショットやサムネイル作成
以下、だらだら続きます。

その1:シェルスクリプトからスクリーンキャプチャ

第1段階として、screencapture コマンドを使ってサイトのキャプチャを取れるようにしてみる。
こんなシェルスクリプト書いてみた。
mac_screencapture.sh

#!/bin/sh
export DYLD_LIBRARY_PATH=""
open -a Safari "$1"
sleep 5
/usr/sbin/screencapture /path/to/save/directory/capture_`date +%Y%m%d%H%M%S`.png

open コマンドで Safari を起動して、ページ読み込みを考えて5秒程スリープ。
で、screencapture コマンドでキャプチャを保存って手順です。
なぜか、DYLD_LIBRARY_PATHという環境変数がエラーになってしまったので無効化してます。
本当は、

unsetenv DYLD_LIBRARY_PATH

とかする気がするんだけどうまくいかなかった。
第1引数でURLを受けるので、

./mac_screencapture.sh http://creazy.net/

とかやると、こういうキャプチャがとれました。
シェルで撮ったキャプチャ
※クリックすると実際のサイズで表示されます。

その2:PHPからスクリーンキャプチャ

さて、その1で撮ったキャプチャはDocやメニューバーなど余計な部分が写ってしまっているので、なんとかブラウザの画面だけ抜き出したいです。
WindowsではCOM経由でウィンドウ情報を取得したりできるのでしょうが、Macではできなそう。
とりあえず、Safariウィンドウの座標XYと縦横幅を自分で調べて切り取るところまでやってくれるPHPスクリプトを書きました。

<?php
if ( $argv ) {             // コマンドモード
$url = $argv[1];
}
else if ( $_GET['url'] ) { // WEBモード
$url = $_GET['url'];
}
$file = '/path/to/save/directory/capture_'.date('Ymd_his').'.png';
$cmd  = 'export DYLD_LIBRARY_PATH="";';
$cmd .= 'open -a Safari "'.$url.'";';
$cmd .= 'sleep 5;';
$cmd .= '/usr/sbin/screencapture '.$file.';';
exec($cmd);
$im = imagecreatefrompng($file);
$safari_x = 39;   // SafariウィンドウのX座標
$safari_y = 98;   // SafariウィンドウのY座標
$safari_w = 1225; // Safariウィンドウのドキュメント幅
$safari_h = 685;  // Safariウィンドウのドキュメント高さ
$new_x = 400;     // サムネイルの横幅
$new_y = $safari_h * $new_x / $safari_w;
$newim = imagecreatetruecolor($new_x, $new_y);
imagecopyresampled($newim, $im, 0, 0, $safari_x, $safari_y, $new_x, $new_y, $safari_w, $safari_h);
imagepng($newim, $file);
?>

一応コマンドでも、WEB経由でも実行できるようにしてみました。
下記のように実行すると、

php -f mac_screencapture.php http://creazy.net/

こういうキャプチャがとれました。
PHPで撮ったキャプチャ
おー、ちゃんとサムネイルになってる!

その3:見ているページをスクリーンキャプチャするBookmarklet

その2までの仕組みで、PHPからサムネイルの出力に成功しました。
ということは、サムネイル生成のキューを貯めといて、cronでサムネイル生成スクリプトを実行とかすればSimpleAPIみたいなサムネイルサービスが作れるな。
でも、やっぱりPHP側でWindow情報を取得できていないのでサービスとしてはまだまだ課題が多過ぎるなぁ。
じゃあ、ローカルで動くサムネイラーとしてもっと有効活用できないかと思って考えついたのが見ているページをサムネイル化してくれるBookmarklet
まずは、サムネイル生成用のPHPを用意しますが基本的にはその2のスクリプトの下記部分がパラメータで渡されるという事だけ違うくらい。
・ウィンドウのX座標
・ウィンドウのY座標
・ウィンドウのドキュメント幅
・ウィンドウのドキュメント高さ
・サムネイルの横幅
ローカルでapache + PHPが起動している状態で下記URLにアクセスできるようにする。
http://localhost/mac_screencapture_bookmarklet.php
・mac_screencapture_bookmarklet.phpのソース

<?php
$file = '/path/to/save/directory/capture_'.date('Ymd_his').'.png';
$cmd  = 'export DYLD_LIBRARY_PATH="";';
$cmd .= '/usr/sbin/screencapture '.$file.';';
exec($cmd);
$im = imagecreatefrompng($file);
$x = $_GET['x']; // ウィンドウのX座標
$y = $_GET['y']; // ウィンドウのY座標
$w = $_GET['w']; // ウィンドウのドキュメント幅
$h = $_GET['h']; // ウィンドウのドキュメント高さ
$new_x = $_GET['size']; // サムネイルの横幅
$new_y = $safari_h * $new_x / $safari_w;
$newim = imagecreatetruecolor($new_x, $new_y);
imagecopyresampled($newim, $im, 0, 0, $x, $y, $new_x, $new_y, $w, $h);
imagepng($newim, $file);
?>

・登録するブックマークレット

javascript:(function(){var win=window,doc=document,ua=navigator.userAgent.toLowerCase(),isua=ua.indexOf('opera')+1||ua.indexOf('safari')+1;if(isua){w=win.innerWidth;h=win.innerHeight;}else{w=doc.documentElement.clientWidth||doc.body.clientWidth||doc.body.scrollWidth;h=doc.documentElement.clientHeight||doc.body.clientHeight||doc.body.scrollHeight;}off=140;x=win.screenX;y=win.screenY+off;size=400;s=doc.createElement('script');s.charset='UTF-8';s.src='http://localhost/mac_screencapture_bookmarklet.php?x='+x+'&y='+y+'&w='+w+'&h='+h+'&size='+size;doc.body.appendChild(s);})();

分かりやすい様に展開

javascript:(function(){
var win  = window;
var doc  = document;
var ua   = navigator.userAgent.toLowerCase();
var isua = ua.indexOf('opera')+1 || ua.indexOf('safari')+1;
// ドキュメントの縦横サイズを取得
if ( isua ) { // Safari or Opera
w = win.innerWidth;
h = win.innerHeight;
} else {
w = doc.documentElement.clientWidth || doc.body.clientWidth || doc.body.scrollWidth;
h = doc.documentElement.clientHeight || doc.body.clientHeight || doc.body.scrollHeight;
}
off = 140;             // ブラウザのメニューバーの縦幅(自分で調べる)
x   = win.screenX;     // ドキュメントのX座標
y   = win.screenY+off; // ドキュメントのY座標(ブラウザのY座標からメニューバーの高さを引く)
size = 400;            // サムネイルのサイズ(任意)
s = doc.createElement('script');
s.charset = 'UTF-8';
s.src = 'http://localhost/mac_screencapture_bookmarklet.php?x='+x+'&y='+y+'&w='+w+'&h='+h+'&size='+size;
doc.body.appendChild(s);
})();

ブクマークレットならJavaScriptでブラウザの情報が直接確認できるので、それをPHPスクリプトに渡してやれば良い。
唯一、ブラウザのメニューバーを除いたドキュメントの座標の取り方が分からなかったので自分で調べた。
ものさしで調べる
適当に見つけたものさしツールで簡単に計る事ができた。
Free Ruler for Mac OS X
で、オレのFirefoxは140pxだったのでそれをoff変数に代入してある。
さて、このブックマークレットを実行すると、
bookmarkletで撮ったキャプチャ
うん、成功。
Bookmarklet版はWindowサイズを動的に取得できるので、結構汎用的かも。
それに、PHPで画像保存するなら、GDなりImageMagickなりで自分好みに変形したものなんかも作れそう。

まとめ

思い付きからついカッとなってやってみたわけで、結果一応は成功したんだけども、どうにも変態的なコードを書いてしまったような気がする。
PHPでってところにこだわったせいか、なんかまわりくどいんだよなぁ。しかも、ローカルでApache + PHP動いてないといけないとか。
なんかスマートな方法あったら教えて下さい。>エラい人

ブラウザの見えていない部分もスクロールしてキャプチャーする方法色々(無料のみ)

-技術情報

執筆者:


  1. 藤棚 より:

    通りすがりにて。
    私は使ってませんが
    http://hmdt.jp/coral/
    がこの目的にはいかがでしょう。
    コマンドラインの簡単な画像処理ならOS X付属のsipsがあります。PHPを使わずとも,簡単な画像の変換,リサイズやトリムは一通りできます。
    screencaptureにこだわるなら, JavaScriptの代わりに,AppleScriptもありかな。osascriptでAppleScriptを呼び出せるので,簡単には以下で。
    osascript -e “bounds of window 1 of application \”Safari\””
    AppleScriptでウインドウのスクロールバーやツールバーの幅を知る方法は,ぱっと見た限りなさそうです。

  2. yager より:

    >藤棚さん
    > http://hmdt.jp/coral/
    おお、良さそうですね。今度ためしてみます。

comment

メールアドレスが公開されることはありません。

関連記事

「FileZilla」Macで使える”Window風”なFTPクライアント

今回はMac用のFTPクライアントソフトのご紹介。 ・FileZilla – The free FTP solution Macがメインマシンになってから早1年以上立ちますが、FTPクライ …

VirtualBox 3.1.4 for Mac に Windows XP をインストール

以前、図解:Windows7 beta を VirtualBox for Mac OS X にインストールする手順(ベータに付き全部無料)というエントリーで書いた通り、どうしてもWindowsで確認し …

no image

改めまして、dolipoのお勉強

前に書いたdolipo(というかpolipo)についての解説エントリーにアクセスが続いています。 ・Macのネット環境高速化「dolipo」はナゼこんなに速いのか ・・・なんですが、この頃やたらと@I …

Google:Gmailが携帯からも使えます

日本語でも3キャリアに対応したようです。 メールの閲覧、返信 — いつでもどこでもメールを閲覧、作成できます。Gmail はお使いの端末に合わせて最適化されるので、どこからでもメールにアクセスできます …

「パケ・ホーダイ」にして使い倒したい携帯サイト

先月、貧乏家族のもとに悲しいお知らせが届きました。 オ、オレの携帯代が1万円超えとるやないか! 電話キライ、メールは相方としかやらないオレは超ライトユーザだったはずが何で?・・・って、実は理由は分かっ …

スポンサードリンク

スポンサードリンク