パソコン系

ドラッグ&ドロップでファイルアップロード

「HTML5とJavascriptによるドラッグ&ドロップ操作でファイルなどをサーバにアップロードするコード」です。いざ作ろうと思って調べてみると古い情報ばかりでどうにもこうにもアレだったので、わりと最近のFirefox、Safari、IE、Chromeで動くようなものを作ってここに置いときます。

index.html

<html>
<head>
<meta charset="UTF-8">
<style type="text/css">
#droparea {
 background-color: #ddd;
 border: dashed 4px #bbb;
 border-radius: 20px 20px 20px 20px;
 width: 400px;
 padding: 20px;
 font-family: Century Gothic;
 font-size: 36px;
 text-align: center;
 color: #bbb;
}
#droparea.dropover {
 background-color: #eee;
 border: dashed 4px #ccc;
 color: #ccc;
}
</style>
<script type="text/javascript">
window.onload = function( ) {
 var msg = document.getElementById( 'message' );  var darea = document.getElementById( 'droparea' );
 darea.addEventListener( 'drop', function( event ) {   var dt = event.dataTransfer;   var files = dt.files;
  var fd = new FormData( );   var xhr= new XMLHttpRequest( );
  event.preventDefault( );   hideDropping( );
  fd.append( "a", "This is A" );   fd.append( "b", "This is B" );   for ( var i = 0, len = files.length; i < len; i++ ) {    fd.append( 'file[]', files[ i ] );   }
  xhr.open( "POST", encodeURI( "upload.php" ) );   xhr.send( fd );
  xhr.upload.onprogress = function( evt ) {    msg.innerHTML = Math.floor( (evt.loaded / evt.total ) * 100 ) + '%';   }
  xhr.upload.onloadend = function( evt ) {    msg.innerHTML = '100% Successfull';    setTimeout( function ( ) { msg.innerHTML = '&nbsp'; }, 5000 );   }
  xhr.onreadystatechange = function ( evt ) {    if ( xhr.readyState == 4 ) {     if ( xhr.status == 200 ) {      if ( xhr.responseText.length > 1 ) {       msg.innerHTML = xhr.responseText;       setTimeout( function ( ) { msg.innerHTML = '&nbsp'; }, 7000 );      }     } else {      msg.innerHTML = "can't access to the server";      setTimeout( function ( ) { msg.innerHTML = '&nbsp'; }, 7000 );     }    }   };  } );
 darea.addEventListener( 'dragover', function( evt ) {   evt.preventDefault( );   evt.dataTransfer.dropEffect = 'copy';   showDropping( );  } );
 darea.addEventListener( 'dragleave', function( evt ) {   hideDropping( );  } );
 function showDropping( ) {   darea.classList.add( 'dropover' );  }
 function hideDropping( ) {   darea.classList.remove( 'dropover' );  }
}; </script> </head> <body>
<div id="droparea" effectAllowed="move"> Drop files here!<br> <span id="message">&nbsp;</span> </div>
</body> </html>

update.php


<?php
 //print $_POST[ "a" ]."<br>\n";  //print $_POST[ "b" ]."<br>\n";
 $uploaddir = '/path to directory/';
 foreach ( $_FILES[ "file" ][ "error" ] as $key => $value ) {   $file_name = basename( $_FILES["file"]["name"][$key] );   $file_type = $_FILES["file"]["type"][$key];   $file_size = $_FILES["file"]["size"][$key];   $file_temp = $_FILES["file"]["tmp_name"][$key];
  if ( $file_size > 10000000 ) {    print "err:data size > 10MB";    return;   }
  //print $file_name." ".$file_type." ".$file_size." ".$file_temp."<br>\n";
  $status = "error";
  if( is_uploaded_file( $file_temp ) )    $status = move_uploaded_file( $file_temp, $uploaddir.$file_name ) ? 'success': 'error';
  //print $status."<br>\n";  }
?>

ファイルサイズのチェックを upload.phpの中で行っていますが、index.htmlのなかでやったほうがいいですよね。エラーメッセージの表示テストのため、あえてこうしてあります。

(少し書きかえれば)ファイルタイプを調べてアップロードできるファイルとできないファイルを判別するとか、選択したテキストをドラッグ&ドロップで送信することもできるようになります。

実行の様子:

Firefoxで index.htmlを表示しているところです。線種を dashedにして borderの角を丸くすると、角がつぶれるのが超絶気になります。IEではきれいに点々のままコーナーが丸くなるんですけど。

HTML5 Javascript File Drag & Drop

デスクトップからファイルをドラッグしてきます。1つでも複数でもOKです。ドロップ領域に入ると領域がハイライト表示になります。

HTML5 Javascript File Drag & Drop

ファイルをドロップするとサーバへの送信が始まります。データ送信の進捗がパーセント表示されます。ファイル各々の進捗ではなく、”全体”の進捗です。

HTML5 Javascript File Drag & Drop

送信がおわり、サーバのほうでエラーなく処理されていれば↓のようになります。スペルミスしていて、ただしくは"Successful"(笑)

HTML5 Javascript File Drag & Drop

update.phpでファイルサイズ制限を 100kバイトに変更してファイルをアップしてみた結果。このスクリプトでは100kバイト以上のファイルに行きあたった時点で処理終了するようになっています。

HTML5 Javascript ファイル アップロード ドラッグ ドロップ

 

 

NVIDIA JetsonTK1 計算性能実測

ふぅ〜。昨年末に買ったNEWアイテム「NVIDIA Jetson TK1」で年明けからずーっと遊んでます!

”組み込みスーパーコンピューター ”というふれこみにうっかり釣られて入手してしまったのですが、cudaコア192個搭載でGPUのクロックがピーク0.852GHz、1クロックで積和計算1回とのことで、単精度浮動小数点数(以下 単精度 倍精度)計算理論値性能 326Gflops (192*0.852*2、そしてもしや倍精度でも100G超???)。それが127mm四方の基板に乗ったシングルボードコンピュータでのご提供ときたら、わくわくする人はワクワクしますよね〜。何台か買ってクラスタ構築!!と夢はひろがるばかりです。が、はたしてその実際の性能は夢の大きさに相応しいものなのかどうか? ここ数日は計算能力の計測にはまっていました。

いくつかの条件で計測してみました(共通:Xのデスクトップ環境が動作したまま)。

1.Octaveで行列計算

・CPU: ”通常パッケージ”版のOctaveで単精度、倍精度行列計算

・GPU: cuBLAS acceleratedな Octaveをビルドし、単精度、倍精度行列計算

2.Rで行列計算

・CPU: ”通常パッケージ”版のRで単精度、倍精度行列計算

・GPU: cuBLAS acceleratedな Rをビルドし、単精度、倍精度行列計算

3.C/C++で行列計算

・CPU: ふつーに forループで単精度、倍精度行列計算

・GPU: cuBLAS関数をつかって、単精度、倍精度行列計算

結果:

1.Octave-3.8.2

N="mat size"; A=double(randn(N)); B=double(randn(N));
start=clock(); C=A*B; elapsedTime=etime(clock(),start);
disp(2*N*N*N/(elapsedTime*1e+9));
※単精度のときは、single()としました。
mat size Gflops
double precision single precision
CPU GPU CPU GPU
32 0.19 0.04 0.19 0.03
64 0.84 0.20 1.00 0.28
128 2.22 1.30 2.60 1.45
256 2.95 4.40 3.65 9.00
512 3.23 8.30 3.83 30.00
1024 3.32 10.70 3.89 76.00
2048 3.37 11.60 3.93 121.00
4096 3.37 11.20 3.97 145.00
8192 3.13 *1
3.98 62.00

2.R-3.1.2

N="mat size";
A<-matrix(0.01*1:0.01*N*N, N, N); B<-matrix(0.01*1:0.01*N*N, N, N);
startT<-proc.time()[3]; C<-A%*%B; endT<-proc.time()[3];
2*N*N*N/((endT-startT)*1e+9);
※Rはデータはすべて倍精度で持つらしいです。
mat size Gflops
double precision single precision
CPU GPU CPU GPU
32 0.07 0.03 - -
64 0.52 0.17 - -
128 0.83 1.00 - -
256 0.86 3.40 - -
512 0.81 6.60 - -
1024 0.74 7.50 - -
2048 0.73 10.80 - -
4096 0.66 10.80 - -
8192 0.62 *1 - -

3.C / C++

倍精度版:cublasDgemm使用 testdgemm.cpp
単精度版:cublasSgemm使用 testsgemm.cpp
mat size Gflops
double precision single precision
CPU GPU CPU GPU
32 0.20 2.02 0.21 1.96
64 0.17 9.76 0.19 15.78
128 0.14 11.29 0.14 66.30
256 0.12 11.97 0.13 104.17
512 0.06 12.29 0.11 180.44
1024 0.03 12.65 *2 204.72
2048 0.03 12.81 - 209.88
4096 *2 11.77 - 204.35
8192 - *1 - 150.87

*1 cudaMalloc()が allocation errorとなって計算できませんでした。

*2 計算に時間がかかりすぎてプログラムがなかなか終了しないのでもうヤメw

参考
インテル® Core™ i7-3770 3.4GHz Ubuntu12.04LTS Octaveで D.P.12Gflops S.P.15Gflopsほど。
インテル® Core™ i7-4790 3.6GHz Ubuntu14.04LTS Octaveで D.P.15Gflops S.P.30Gflops ほど。

C/C++でのCPUのflops値が低いような気がしますが、プログラムが間違っているとか時間の測り方が間違っているとか原因があるのかもしれません。

 

結論:"スーパーコンピュータ"というキーワードと理論値性能に過度な期待を寄せてはいけません。スーパーコンピュータのテクノロジーに触れることもできる楽しい電子工作アイテム、といったところが実際ではないでしょうか。倍精度計算が予想を完全に裏切る結果となりましたが、そもそも車載組み込みやモバイル端末で厳密な科学計算する必要なんかあまりないだろうし、画像処理やゲームするぐらいなら単精度で十分なんでしょうね。さて、小規模クラスタ組んでOpenMPIとかもいじってみる予定もあって楽しみなんですが、さしあたり次はOpenCVにいってみようかな。OpenCVはオプションでcuBLASサポートしていて、WITH_CUBLAS:ONにして既にビルド済となってはいます。どんな変化があらわれるのか? っていうか、すでにXiaomiがTegraK1SOC搭載したMiPadての販売中だけどw

 

Canvas で Martin Attractor

Canvasでお絵かき第2段!!今度はマーチンアトラクターを描いてみました。しかも色付きです。

Xn+1 = Yn - sign( Xn ) abs( b Xn - c )0.5

Yn+1 = a - Xn

ブラウザのJavascript機能をONにし、ぜひこちらからお試しください> martinAttractor.html

Barry Martin's Hopalong Attractor on CanvasBarry Martin's hopalog attractor on Canvas
Barry Martin's Hopalong Attractor on CanvasBarry Martin's hopalog attractor on Canvas

ページを開いて最初に表示された模様に、+ーボタンで微調整をかけていくといったかんじの使い方です。ページを再読込すると絵柄が変わります。最初の絵柄がモノクロだったり極端に”疎”な場合は概ねハズレなので、ページを再読み込みしましょう。

20年ほど前、SunMicrosystems SPARCStationの SunOS4.1.xとかで MartinViewというスクリーンセーバーが動いていて、この図柄が表示されてました。ビデオカードがモノクロだったので、黒背景に白い点々でパターンが浮かび上がってくるという代物だったんですが、自動的に変化するパラメータにあわせてアニメートする図柄にしばしば見入っていました。後にカラーでも見ましたが、カラーは色がごちゃまぜでちょっと汚かった印象が残ってますね。

クリフォードアトラクターもそうですが、パラメータを変化させて生成された図をパラパラアニメにしたら、きれいな動画ができそうですねー。

Canvas で Clifford Attractor

HTML5の Canvasというものを試してみたくて、先週末からフラクタル系のお絵かき勉強をしていました。それでまた、どうしてもクリフォードアトラクター(Clifford Attractor)を描いてみたくて。

Xn+1 = sin( a Yn ) + c cos( a Xn )

Yn+1 = sin( b Xn ) + d cos( b Yn )

で、先ほどひとまず完成。モノクロ描画をしたら墨汁をたらしたみたいでなかなかいい感じに。というより、色をどう変化させればいいか考えるのがめんどくさかったのでモノクロに、、。

最近のFireFoxやSafariでは動作確認しています。そのほかのブラウザでもCanvasに対応しているものであればたぶん実行できると思います。もう専用ソフトをDLしてインスコして、、なんて必要なくクリフォードアトラクタを楽しめますね〜。ブラウザのJavascript機能をONにし、ぜひこちらからお試しください> cliffordAttractor.html

iPhone5 iOS8.1のSafariでも動きました!「detail」表示には計算にかなり時間かかりますけど。
※ WWWブラウザのウィンドウサイズを変更すると再描画するようになっています。
※ プレビュー表示(粗い点表示)では5万回、詳細表示では800万回、上記の式を計算します。
# Web workersを使っているので、詳細表示計算中でもブラウザがちゃんと応答します。

クリフォードアトラクター

クリフォード・アトラクター1

クリフォード・アトラクター3

お好きな方は、こういうのほんとに好きだと思います笑。マウスクリックのし過ぎで腱鞘炎になってしまったりマウスを壊してしまったりせぬようお気をつけくださいませ。

MATLABで画像再構成

X線CT、MRIとか、”ミューオンで火山のレントゲン写真”でも使われている画像処理の基礎となる「画像再構成」。

MATLABで画像再構成の動作確認をしたくてつくったプログラムをUP。「あ、っぽい画像でた。終了~」というかんじで個人的に最低限の動作を確認しただけのものなので、UIもコードもほんとうに適当です笑。が、このまま捨てるのももったいないので。処理の各部、FFTの理解が不完全で、どこか間違っていると思いますのご注意を。

FBP法と、2次元フーリエ変換法(座標変換アルゴリズム3種)で、合計4つのサンプルについて。画像回転、座標変換、FFTとか逆FFTの関数はMATLAB備えつけのものを使用しています。それぞれオリジナルの関数にリプレイスできますね。入力はサイノグラム。出力は再構成された画像。

 

1.FBP(=Filtered Back Projection)法 画像変換はMATLABの関数を使用 (FBP_with_MATLAB_image_TRANS_func.zip)。意外ときれいな結果。投影するデータを回転するのではなく、投影されたデータのほうを回転しているので、再構成画像が180度回転したものとなっています。

画像再構成 FBP法

 

2.2次元フーリエ変換法 直交座標-極座標変換にMATLABの関数を使用 (2DFFT_with_MATLAB_coord_TRANS_func.zip)。へぇー、って感じ。

画像再構成 2次元フーリエ変換法 MATLABの座標変換関数を使用

 

3.2次元フーリエ変換法 直交座標-極座標変換変換(座標変換&データ補完)に「Excelによる画像再構成入門」で紹介されているアルゴリズムを利用しています (2DFFT_with_StudyBook's_coord_TRANS_func.zip) 。参考書座標変換&補完のExcel式が正しくMATLABに変換できているか自信ありません。とりあえず画像出た笑 表示がカラーであることに意味はないです。

画像再構成 2次元フーリエ変換法 Excelによる画像再構成入門の座標変換関数を使用

 

4.2次元フーリエ変換法 直交座標-極座標変換変換部分を自分で書いたもの(2DFFT_with_ORIGINAL_coord_TRANS_func.zip) 。ある座標について系を変換後、その値を周囲8点にコピペして補完したつもり、という安直な考え方。精度もよくないし、そのうえ処理にとても時間がかかるという代物。周波数が低い部分はデータ数が多いので、↓のようなサンプルデータならおおまかな画像は得られる。周波数が高い部分にノイズが多いのが弱点。

画像再構成 2次元フーリエ変換法オリジナル(笑)の座標変換関数を使用

 

1.MATLABを起動し、

2.MATLABプロンプトで「guide」と入力しリターン

3.「GUIDEのクイックスタート」というポップアップウィンドウの「既存のGUIを開く」で

4.参照から untitled.fig(もしくはuntitled1.fig)を選択する

5.figファイルのウィンドウが開いたら、緑色の再生ボタンを押してプログラムを実行

6.「・・・MATLABパスが見つかりません」と警告メッセージが表示される場合は 「パスに追加」を押す

★計算が終わるまで沈黙します。計算が終わると結果表示のウィンドウが開きます。

★結果表示まで数十秒~数分かかります(MATLABがハングしたと思って強制終了しないように注意)

 

コンテンツの配信