phpでアップロードした画像のファイル名を取得しよう

まずformでアップロード機能をサクッと作ります。

<?php
if(file_exists($_FILES&#91;'upfile'&#93;&#91;'tmp_name'&#93;)){
	$ext = substr($_FILES&#91;'upfile'&#93;&#91;'name'&#93;, strrpos($_FILES&#91;'upfile'&#93;&#91;'name'&#93;,'.') + 1);
	echo $ext."<br>";
	if(strtolower($ext) !== 'png' && strtolower($ext) !== 'jpg' && strtolower($ext) !== 'jpeg' && strtolower($ext) !== 'gif'){
		echo '画像以外のファイルが指定されています。画像ファイル(png/jpg/jpeg/gif)を指定して下さい';
		exit();
	}

	$tmpname = str_replace('/tmp/', '', $_FILES['upfile']['tmp_name']);
	echo $tmpname;
	// $new_filename = 'profiles/'.$id.'-'.time().'-'.$tmpname.'.'.$ext;
}

?>
<div id="content">
<h2>画像管理</h2>
<hr>
<form action="#" method="POST" enctype="multipart/form-data">
<div id="drag-drop-area">
 <div class="drag-drop-inside">
  <p class="drag-drop-info">ここにファイルをアップロード</p>
  <p>または</p>
  <!-- <input type="file" value="ファイルを選択" name="image"> -->
  <p class="drag-drop-buttons"><input id="fileInput" type="file" value="ファイルを選択" name="upfile"></p>
      <input type="submit" value="送信">
   </div>
  </div>
</form>

アップロード前

アップロード後

うん、上手くいってるようです。
さて、s3をやりましょう。ここまで長かった。

jpgとjpegの違いは何か?

.jpgと.jpegは同じなのか? 二つとも同じJPEGに見えるが、正確には違うようだ。

MS-DOSではファイルの拡張子が3文字までという制約があった
そういえば、.jpegより.jpgの方が良く見ますね。
しかし、現在のosでは4文字も利用できるため、jpegも対応している。

jpgの略は、Joint Photographic Experts Groupで、4文字の拡張子もOKになったので、jpegが追加された?たったそれだけの理由?

Acrobatにてファイルから直接PDF変換を行える形式: .jpg
PDF以外に保存が行える形式: .jpg/.jpeg

.jpgの方がより多くの機能に対応しているようです。

うーん、ITの世界も極めて天才的な設計がある一方で、こういうイマイチよくわからない経緯もあるんですな。

Cannon EOS Kiss Digital X

一眼レフの話をしていたら、何故かCannon EOS Kiss Digital Xをいただきました。

少し試し撮りしましたが、630より面白いです。
表現の幅は広げたいですね。

フィルムカメラを現像して、QRコードでスマホに転送する

EOS630で撮影した写真をPALETTE PLAZAさんでフィルムから現像して、QRコードでiosに転送しダウンロード

現像24枚で700円、スマホ転送サービス500円、現像の所要時間1時間

やっぱり現像はめんどくさい&スマホ転送サービスを使うと画質が落ちるらしい
->どう考えてもデジカメの方がいい
->iphoneのカメラで撮れば、現像なんて面倒なことしなくていい

といいつつ、またフィルムを買ってしまった。
ああああああああああああああああ、、、、、駄目だこりゃ。

で、思ったこと。
1.みんないいカメラを使っている。
2.カメラの撮り方も色々あるっぽい。(素人目では、どういう撮り方がいいのか良くわからない)
3.カメラも大事だが被写体も大事。
4.一眼レフカメラをやってる人は年齢層が高い。
5.あまりやりすぎても本末転倒(プログラミングに時間をかけるべき)だが、カメラもまあまあ面白い

で、一番知りたかったことだが、
6.いいカメラマンの見分け方 ->まだ全然わからないが、経験ある人・カメラに情熱がある人の方が知識が豊富で勉強になりそうだ
これは、今後productをつくっていく上で大事かも。。

オークションで一眼レフ落札したら、フィルムカメラだった!

エンジニアたるもの、写真の意識が高くないと駄目だ、とあるカメラやってる方にインスパイアーされ、ヤフオクで一眼レフを落札

ワクワク^^

届きました。

いいね~この重厚感

あれ、ちょっと待て、これフィルム?

普通そこ間違えるかね。。

といいつつ、速攻でフィルムと電池を買ってしまった。

息抜きに写真でも撮りに行きますかね。

iphoneのカメラとEOSは何が違うのか?

プロでなければ、普通に写真撮る分にはiphoneで十分、と誰かにお聞きしたんだが、
前から気になっていた、iphoneと一眼レフでどれ位性能違うの?

iphone
6s
-live photos(シャッターを切る前後1.5秒ずつの動画も含めて記録する)
-位相差AFセンサー
-手ぶれ補正
-動画画質 4K/30p(フルHDの4倍の情報量)
-有効画素数 1200万画素

X
-1200万画素
-連写速度 約10コマ/秒
-シャッター速度 1/8000~30秒
-4Kビデオ作成
-wifi bluetooth, gps 〇
-レンズF値 広角:1.8, 望遠:2.4
-レンズカバー距離 28-57mm
-174g

Cannon
EOS630(1989年129,700円)
-シャッター1/2000~30秒
-AF方式:TTL位相差検出方式(ズレ検出)、AFモードはワンショット式 /動体予測AIサーボAF、AF検出範囲はEV1~18(ISO100)
-ファインダー:ペンタ固定アイレベル式、倍率0.8倍、視野率94%、交換スクリーン7種完備
-測光・露出制御:複合型SPC素子使用、TTL開放測光シャッタースピード優先式AE/絞り優先式AE/インテリジェントプログラムAE、定点連動マニュアル、オートブラケティング(1/2段±5段階露光可能)、9回まで予約可能の多重露出可能、測光感度分布特性=画面6分割評価測光/中央部分(画面中央約6.5%部)測光(AEロック機能付き)、露出補正±5EV(1/2ステップ)可能、測光連動範囲はEV-1~ 20(ISO100:F1.4)、フィルム使用感度域はISO6~6400、イメージセレクト=AF、AE、巻き上げ、プログラムの組み合わせ7種、カスタムファンクション=7種設定可能

EOS-1D X Mark II(547,800円!?)
-CFカード(タイプI準拠、UDMAモード7対応)CFastカード(CFast 2.0対応)
-約35.9×23.9mm
-CMOSセンサー
-約2020万画素
-DCF2.0 PEG、RAW
-ピクチャースタイル:オート、スタンダード、ポートレート、風景、ディテール重視、ニュートラル、忠実設定、モノクロ、ユーザー設定1~3
-ホワイトバランス
-画像の明るさ自動補正,高輝度側・階調優先,レンズ光学補正
-ファインダー ペンタプリズム使用、アイレベル式 約0.76倍(50mmレンズ・∞・-1m-1)
-オートフォーカス 専用AFセンサーによるTTL二次結像位相差検出方式
-露出制御:約36万画素RGB+IR測光センサー使用、216分割TTL開放測光
-多重露出撮影
-シャッター 電子制御式、フォーカルプレーンシャッター 1/8000~30秒
-ドライブ関係 1枚撮影、高速連続撮影、低速連続撮影、1枚:ソフト動作、ソフト高速連続撮影、ソフト低速連続撮影、セルフタイマー:10秒、セルフタイマー:2秒 高速連続撮影
-外部ストロボ EXシリーズスピードライト E-TTL II 自動調光
-ライブビュー撮影機能
-動画撮影機能 MOV、MP4
-液晶モニター
-再生機能
-有線LAN機能
….

機能が想像以上にあるな。。1989年のEOS630ですら、まだキャッチアップでんぞ。。。

とりあえずシャッター速度は変わらんよう。
画素は2200万だからEOSは倍。1200万でも相当凄いんだろうけど。。よーわからんが。
明るさや、露出補正はなんとなく馴染みやすいが、手振れ補正のアルゴリズムが良くわかりませんね。
手振れ補正は、色々なアルゴリズムの研究が世界中であるようです。
https://library.naist.jp/mylimedio/dllimedio/showpdf2.cgi/DLPDFR008578_P1-93
光学式:カメラの動きをジャイロセンサで検出して、その動きがキャンセルされるようにレンズ、撮影素子を駆動する
電子式:画像処理
->光学式は、カメラそのもの動きを計算しているんですね。

自動運転は画像認識の技術が入っているので、当然カメラと連動した写真系のサービスつくらないと駄目ってことですね。(どれ位掘らないといけないのか、現段階では想像つきません)
呑気に「一眼レフ買って撮影会に行きたい」なんて言ってる場合ではないことは確か。

画像認証 securimage

git hubからdownloadします。
https://github.com/dapphp/securimage

git clone https://github.com/dapphp/securimage.git

早速使ってみます。

<img id="captcha" src="securimage/securimage_show.php">

なにこれ?

つかっていきます。

<?php
if($_POST&#91;"captcha_code"&#93;){
	require_once "securimage/securimage.php";
	$securimage = new Securimage();
	if($securimage->check($_POST['captcha_code'])==false){
			echo "error";
	} else {
		 	echo "success";
	}
}

?>
<form method="POST" name="form" action="">
<img id="captcha" src="securimage/securimage_show.php"><br>
<input type="text" name="captcha_code"><br>
<input type="submit" value="送信" class="submit">
</form>

おおおお

添付ファイルの表示およびダウンロード

表示するphpファイル
写真が2枚の時は、vertical-align:topで上揃えにします。

<style>
#menu {
	border: solid 1px #f0f8ff;
	font-size:small;
	color:#d3d3d3;
	padding-left:10px;
}
#img{
	position: relative;
}
#img img{
	vertical-align:top;
}
</style>
<?php
$id = 15;

$dsn = "mysql:dbname=mail;host=localhost";
$user = "hoge";
$password = "hogehoge";
try {
    $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e){
    print('connection failed:'.$e->getMessage());
}
$sql = "select * from sends where id = '".$id."'";
$stmt = $dbh->query($sql);

$result = $stmt->fetch(PDO::FETCH_ASSOC);
$send_from = $result['username'];
$send_sub = $result['subject'];
$send_body = $result['body'];
$sendtime = $result['sendtime'];
$file1 = $result['file1'];
$file2 = $result['file2']; 

echo "<h3>".$send_sub."</h3>";
echo "From: ".$send_from. "<br>";
echo $sendtime. "<hr>";
echo $send_body. "<br>";
if(!empty($file2)){
	echo "<br><div id=\"img\"><img src=\"".$file1."\"> <img src=\"".$file2."\"></div><br>";
	echo "<a href=\"wa.php?id=".$file1."\">1.ダウンロード</a> <a href=\"wa.php?id=".$file2."\">2.ダウンロード</a><br>";
}elseif(!empty($file1)){
	echo "<br><img src=\"".$file1."\"><br>";
	echo "<a href=\"wa.php?id=".$file1."\">ダウンロード</a><br>";
}
?>
<br>
<div id="menu"> <a href="?compose=reply&inbox=<?php echo $id; ?>">返信する</a> | <a href="?path=todelete&inbox=<?php echo $id; ?>">削除</a> | <a href="?path=tojunk&inbox=<?php echo $id; ?>">ジャンク</a></div>

ダウンロード押下すると、wa.phpで生成した画像ファイルをダウンロードします。
拡張子に応じて、switch文で切り替えます。
wa.php (web access ※outlookの真似をしました)

<?php 

$fpath = $_GET&#91;'id'&#93;;
$ext = substr($fpath, strrpos($fpath, '.') + 1);

$date = date(Ymdhis);

switch ($ext) {
	case 'jpeg':
		$fname = "".$date.".jpeg";
		header('Content-Type: application/force-download');
		header('Content-Length: '.filesize($fpath));
		header('Content-disposition: attachment; filename="'.$fname.'"');
		readfile($fpath);
		break;
	case 'gif':
		$fname = "".$date.".gif";
		header('Content-Type: application/force-download');
		header('Content-Length: '.filesize($fpath));
		header('Content-disposition: attachment; filename="'.$fname.'"');
		readfile($fpath);
		break;
	case 'png':
		$fname = "".$date.".png";
		header('Content-Type: application/force-download');
		header('Content-Length: '.filesize($fpath));
		header('Content-disposition: attachment; filename="'.$fname.'"');
		readfile($fpath);
		break;
	default:
		$fname = "".$date.".jpg";
		header('Content-Type: application/force-download');
		header('Content-Length: '.filesize($fpath));
		header('Content-disposition: attachment; filename="'.$fname.'"');
		readfile($fpath);
		break;
}
?>

まーいいんじゃないでしょうか。

添付が1枚の時

つなげると、

OK! Good!

さて、idはauto incrementではなく、乱英数字8桁くらいにしたいですね。

$str = array_merge(range('a','z'), range('0', '9'), range('A', 'Z'));
$r_str = null;
for($i = 0; $i < 8; $i++){
	$r_str .= $str[rand(0, count($str) - 1)];
}
echo $r_str;

ほい

Gmail、hotmail、Yahoo!添付ファイル受信時の表示とURLの設計

gmail
-> 写真が表示されます。

hotmail
-> 写真を表示

yahoomail
-> 写真表示

ぬぬぬ、なるほど、基本は表示ですね。

ダウンロード時のURI
gmail:https://mail.google.com/mail/u/0/?ui=2&ik=10桁の英数字&view=att&th=16桁の英数字&attid=0.1&disp=safe&realattid=f_9桁の英数字&zw
hotmail:https://attachment.outlook.live.net/owa/hoge@hotmail.com/service.svc/s/GetAttachmentThumbnail?id=AQMkADAwATE2MjYxLTU3MmEtMGU4ZC0wMAItMDAKAEYAAAPamN5TZvIjQZibMQuFo… 以下略
yahoo: https://jp.mg5.mail.yahoo.co.jp/neo/launch?.rand=13桁の英数字#

なんじゃこりゃ?URIだけ見ると、yahooは比較的シンプルに見える。
hotmailは、subdomainがattachmentに変わって、id, x-owa-canary(意味不明?), tokenなどのパラメーターが色々ついています。※owaはoutlook web accessの略ですね。
これ、どういう設計になってるんでしょう???
もう、誰だよ、これつくってるの。

inputで選択した複数画像をブラウザ上で表示させる

<style>
.thumb {
	height: 100px;
	width: 100px;
	border: 1px solid #000;
	margin: 10px 5px 0 0;
}
</style>

<input type="file" id="files" name="files&#91;&#93;" multiple /><br>
<output id="list"></output>
<script>
	function handleFileSelect(evt){
		var files = evt.target.files;

		for (var i = 0, f; f = files[i]; i++) {

			if (!f.type.match('image.*')) {
		        continue;
		      }

			var reader = new FileReader();

			reader.onload = (function(theFile){
				return function(e){
							var span = document.createElement('span');
		          span.innerHTML = ['<img class="thumb" src="', e.target.result,
		                            '" title="', escape(theFile.name), '"/>'].join('');
		          document.getElementById('list').insertBefore(span, null);
		        };
		      })(f);

			reader.readAsDataURL(f);
		}
	}

	document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>

初期

画像を選択

選択後
なんだこりゃーー!!すげー

では繋げてみましょう。

<?php
	  for ($i=0; $i<count($_FILES&#91;'files'&#93;&#91;'name'&#93;); $i++) {
    $file_ext = pathinfo($_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93;, PATHINFO_EXTENSION);
    if (/*FileExtensionGetAllowUpload($file_ext) && */ is_uploaded_file($_FILES&#91;"files"&#93;&#91;"tmp_name"&#93;&#91;$i&#93;)) {
      if(move_uploaded_file($_FILES&#91;"files"&#93;&#91;"tmp_name"&#93;&#91;$i&#93;, "upload/img/".$_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93;)) {
          echo $_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93; . "をアップロードしました。<br>";
      } else {
        echo "ファイルをアップロードできません。<br>";
      }
    } else {
      echo "ファイルが選択されていません。<br>";
    }
  }
  //アップロードできるファイルに拡張子の制限をかけたい時
  function FileExtensionGetAllowUpload($ext){
    $allow_ext = array("gif","jpg","jpeg","png","eps");
    foreach($allow_ext as $v){
      if ($v === $ext){
        return 1;
      }
    }
    return 0;
  }

?>
<style>
.thumb {
  height: 100px;
  width: 100px;
  border: 1px solid #000;
  margin: 10px 5px 0 0;
}
</style>
<form action="#" method="post" enctype="multipart/form-data">
<input type="file" id="files" name="files&#91;&#93;" multiple />
<input type="submit" value="Send">
</form>
<output id="list"></output>
<script>
  function handleFileSelect(evt){
    var files = evt.target.files;

    for (var i = 0, f; f = files[i]; i++) {

      if (!f.type.match('image.*')) {
            continue;
          }

      var reader = new FileReader();

      reader.onload = (function(theFile){
        return function(e){
              var span = document.createElement('span');
              span.innerHTML = ['<img class="thumb" src="', e.target.result,
                                '" title="', escape(theFile.name), '"/>'].join('');
              document.getElementById('list').insertBefore(span, null);
            };
          })(f);

      reader.readAsDataURL(f);
    }

    var output = [];
    for (var i = 0, f; f = files[i]; i++) {
      output.push('<li><strong>', escape(f.name), '</strong>(', f.type || 'n/a', ') -',
        f.size, ' bytes, last modified: ',
        f.lastModifiedDate.toLocaleDateString(), '</li>');
    }
    document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
  }

  document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>

ほお

php側にもちゃんと渡されています。