CakePHP」タグアーカイブ

CakePHP + jQuery webcam plugin

プロフィールの画像を直接取得できればいいかなぁって思い、このプラグインを使ってみました。

最初は、jQueryだけでwebカメラの操作ができるんだって思っていました。
でも実際は、flashとjQueryを組み合わせて使います。

概要

  • ウェブカメラからの画像を画面にキャプチャする(html5 canvas)
  • ウェブカメラからの画像を取得しサーバー上に保存する

※デスクトップキャプチャソフト等も使えます。

完成イメージ

参考サイト

配布元
Ajalog.7z:jQueryでWebカメラを制御する

環境

  • XAMPP
  • CakePHP1.3.5
  • jQuery1.4.3
  • jQuery webcam plugin

準備

  1. 配布元からファイルをDL&展開
  2. 展開してできたファイルを適当な場所に設置(e.g. app/webroot/js/jquery.webcam.js app/webroot/swf/jscam.swf and jscam_canvas_only.swf)
  3. ウェブカメラを接続 or デスクトップキャプチャ等のソフトをインストール

webcam plugin

swfファイル

次の2つがあります。使いたい状況に応じて設定します。

  1. jscam.swf
  2. jscam_canvas_only.swf

1.はすべての機能が使えます。
2.はcanvasに描画する機能のみです。サーバー側にsaveしたい場合は1.を使います。

function

  • capture(delay):delay秒後にcaptureします
  • save(file): キャプチャ画像を保存 mode:”save”時にfile名を設定するとサーバー側に保存
  • getCameraList():有効なカメラリストの取得
  • setCamera(index):getCameraList()のindexでカメラを切り替える

mode

  • callback
  • save
  • stream

の3種類があります。
callbackは各コールバック関数を呼びます。
saveはcallbackと変わりませんが、save(file)を実行するときにデータを指定したファイルパスへ送信します。
streamは配布元を参照して下さい。

他のパラメータは、配布元を参照してください。

キャプチャした画像をcanvasに描画する処理は上記の参考サイトに書いてあるので、ここではサーバー側の処理を行います。

mode:“save”
onSave():画像の保存完了後に呼び出される。
保存画像を表示させるには、
このコールバックの中でページを書き換え処理を入れるか、
リダイレクトを行えばいいと思います。

jQuery関係のファイルは適当な場所で読み込む。
app/views/webcams/upload

	<strong>Webカメラから画像を設定</strong>
		<div id="jquery_camera"></div>
		<div id="camerastatus" style="margin-left: 10px;">
			<strong>カメラリスト</strong>
			<ul id="cams"></ul>
			<div id="status"></div>
			<button id="btn">キャプチャ</button>
		</div>
		<?php $this->Html->scriptStart(array('inline' => false)); ?>
			$(function(){
				var width = 320;
				var height = 240;
				$("#jquery_camera").webcam({
					width: width, // webcamの横サイズ
					height: height,// webcamの縦サイズ
					mode: "save",
					//swffile: "/swf/jscam_canvas_only.swf",
					swffile: "/swf/jscam.swf",
					// captrue(delay)が実行されたとき、残り時間を引数にもち、
					// 1秒ごとに呼び出される
					// e.g. delay = 5のときは remainが5,4,...,1と変化して呼び出される。
					onTick: function(remain) {
						if(0 == remain){
							$("#status").text("Cheese!");
						}else{
							$("#status").text(remain + "seconds remaining...");
						}
					},
					// mode:saveの場合
					// サーバー側での保存が完了し、サーバーからのレスポンスがくると呼ばれる
					onSave : function () {
						//キャプチャした画像をwebcam.saveメソッドで保存すると呼び出される。
						$("#status").text("done!!");
						var url = "リダイレクト先";
						window.location = url;
					},
					// Capture時に呼び出される
					onCapture: function() {
						webcam.save('/users/upload/<?= $this->data['User']['id'] ?>');
					},
					// debug用
					debug: function(type, string) {
						$("#status").html(type + ": " + string);
					},
					// 読み込み完了時
					onLoad: function() {
						var cams = webcam.getCameraList();
						for(var i in cams) {
							$("#cams").append("<li>" + cams[i] + "</li>");
						}
						$("#btn").click(function(){
							webcam.capture();
						});
					}
				});
			})
	<?php $this->Html->scriptEnd(); ?>

CakePHP

app/controllers/webcams_controller.php

・・・
	function upload($id = null){
		$this->laout = '';
		$updir = ini_get('upload_tmp_dir');
		$str = file_get_contents("php://input");
		$filepath = $updir . DS . 'user.jpg';
		file_put_contents($filepath, pack("H*", $str));
		// これ以降にDBへの登録処理をおこなう
		// e.g.下の処理はMediaPluginを使った時の処理の例
		$this->data['Picture']['title'] = '';
		$this->data['Picture']['description'] = '';
		$this->data['Picture']['model'] = 'User';
		$this->data['Picture']['foreign_key'] = $id;
		$this->data['Picture']['file'] = $filepath;
		if($this->Picture->save($this->data)){
			@unlink($filepath);
			exit();
		}else{
			//失敗時の処理
		}
・・・

CakePHP + jQuery elFinderでWEB上ファイル管理

web上でファイル管理ができないかなって思っていたところ、elFinderなるものをみつけた。
これをCakePHPに組み込んでみました。別にCakePHPである必要はないのですが。。

作成イメージ

普通に設定すると、クローラーに参照されたり、ファイルのアドレスを直接入力されるとみえてしまいます。
ここでは、ファイルの管理画面にはログインが必要であることを想定します。
保存先のディレクトリにBasic認証をかけて、サイトにログイン状態であれば、Ajaxを利用し自動でBasic認証するようにします。

必要な環境

  • php
  • jQuery,jQuery UI

Download

ここから

ダウンロードしたものをwebrootの適当な場所に配置する。
展開するとjs,css,imageのようなフォルダができるのでそれをそのまま配置していけばOK。

設定

設定は上記のサイトおよび、展開したファイルのに含まれるサンプルのhtmlを参照。

ファイルの保存先

webroot/hoge
.htaccessでBasic認証をかけます。

自動で認証

下記のサイトのライブラリをそのまま使用しました。
Ajaxで基本認証+SSL

/app/view/elfinder/index.ctp

<script>
    $().ready(function(){
        // 引数には適当な値を入力して下さい。user,passwordがBasic認証に必要なユーザ名とパスワードです。
        sendRequest(callback,data,method,url,async,sload,user,password);
        // 以下、elfindeの処理
        ..........
    });
</script>

ユーザ名とパスワードをそのまま記載するのはあまりよろしくないと思うので、
/app/controllers/elfinder_controller.php

.....
function get_basic(){
    $this->layout = 'ajax';
    // ユーザ名とパスワードを返す処理
    // e.g.
    $data = array('user' => 'hogehoge', 'passwd' => '********');
    header('Content-type: application/json; charset=UTF-8’);
    echo json_encode($data);
}
.....

等の処理をPHP側にいれ、ajaxでデータを取得すればよいかと思います。

これでファイルの管理画面にアクセスしたときに、Basic認証のダイアログを出すことなくアクセス出来るようになると思います。

最初に直接ファイルのアドレスを打って、ダイアログが出ることたしかめ、
サイトからアクセスすると出ないことを確認した方がいいかもしれません。

ブラウザを閉じると、Basic認証が解除されるので、再び直接アクセスするとダイアログが表示されるはずです。

もっといい方法を知っている方がいれば教えてください。

CakePHP MediaPluginを使った携帯からの画像アップロード

概要

詳しいコードは、省略しています。
MediaPluginを使って携帯からの画像をアップロードしたときのことをメモしておく。
携帯からの画像アップロード方法は次の2通り。

  • 画像をメールに添付する
  • PCと同じ方法(inputタグのfile属性を使う)

2番目の方法は、対応しているものとしていないものがある。
まだ対応しているものは少ないと思われる。

環境(使用するもの)

  • CakePHPのShell
  • MySQL
  • MediaPlugin
  • メールサーバ
  • QdmailReciever

完成イメージ

完成イメージ

処理概要

  1. メールにファイルを添付し、登録用のアドレスに送信
  2. 受け取ったメールをCakeのShellで処理
  3. 登録用のアドレスを記載したメールを返信
  4. htmlから画像を登録
  5. fileをMediaPluginで処理

準備

  • MySQLに仮登録用の適当なテーブルを作成し、画像のデータを登録するフィールドを作成(BLOB型)する。
  • メールを送信してもらうアドレスを作成する。(nologin)
  • 作成したアドレスに画像を添付したメールを送信してもらう。

仮登録:サーバ側の処理

  • 受信したメールをShellに渡す。
  • QdmailRecieverを使って、メールの内容を取り出す。
  • 必要なデータをDBに仮登録する。
  • 登録用のURLの作成し、メールを返信。

登録

  • ユーザにURLにアクセスしてもらう。
  • このときにDBに保存していたデータから、画像を作成
  • 登録のボタンを押下してもらう。
  • 一時ファイルの削除などの後処理

気をつけるべきことは次の2つ!!

  1. ファイル保存用のテーブルのfileフィールドにファイルのパスを記載する。
  2. ファイルを作成するのは、ユーザが指定したURLにアクセスしたとき。

2の理由は、Shellで処理するときにファイルを作成すると、ファイルの所有者がnobodyになってしまい、サーバー側で後でファイルの削除が出来なくなるためです。

photo_regist_controller.php

<?php
// ・・・
$this->data['Attachment']['file'] = "ファイルへのパス"
// e.g. "/tmp/hoge.jpg"
?>