その漫画自炊オタクはImageJマクロに恋をする

プログラミングを用いた、自炊漫画の画像処理

【続・改良版】スキャナ読み取り直後に数秒間だけ画像表示させるMacro (ver.3)

 





前回同様、「データ確認のためちょこっとだけ画像表示させるマクロ」の改良版(ver.3)です。

 

//FileWatcher_Modoki.ijm
//Detect if there are "New created files" or "Modified files" in selected dir.

version = "3.3.0";

print("");
print("FileWatcher_Modoki.ijm");
print("ver",version);
print("");



checkImageTime = 1800;

var width = 570; //seinen size comic
//var width = 550; //syounen size comic
var height = 1000;



//define var
var zeroTime;
var tempTime = 0;
var flagDetect = 0;
var sCount = 0;
var RECENT = newArray("","","","","");

//select dir
dir = getDirectory("Choose a Directory");
print("Watching :",dir);
print("");

//get zeroTime
zeroTime = getTime();

//Main ope
getDateAndTime(year0,month0,week0,day0,hour0,min0,sec0,msec0);
var min = 0;

while(min < 30){
	//Show WaitingCount
	getDateAndTime(year,month,week,day,hour,min,sec,msec);

	msec = floor(msec/10 -msec0/10);
	if(msec < 0){
		msec = 100+msec;
		sec = sec-1;
	}
	sec = sec - sec0;
	if(sec < 0) {
		sec = 60 + sec;
		min = min -1;
	}
	min = min - min0;
	if(min < 0) {
		min = 60 + min;
		hour = hour -1;
	}
	hour = hour - hour0;
	if(hour <0){
		hour = 24 + hour;
	}

	bytes = parseInt(IJ.currentMemory());
	bytes = d2s(bytes/1000000,2);

	print("\\Update:"+pad2(hour)+":"+pad2(min)+":"+pad2(sec)+":"+pad2(msec),"<",bytes,"MB >");

	//Detect New File
	list = getFileList(dir);
	
	for(i=0;i<list.length;i++){
		lastModifiedTime = File.lastModified(dir + list[i]);
		lastModifiedTime = parseFloat(lastModifiedTime);
	
		if(lastModifiedTime > zeroTime){
			call("ij.gui.ImageWindow.setNextLocation",0,0);
			open(dir+list[i]);
			setLocation(0,0,width,height);
			close("\\Others");
			wait(checkImageTime);

			flagDetect = 1;
			if(lastModifiedTime > tempTime) tempTime = lastModifiedTime;

			sCount++;
			RECENT[sCount%5] = list[i];
			
		}else if(lastModifiedTime == zeroTime){
			if(fileExistInArray(list[i],RECENT) == 0){
				call("ij.gui.ImageWindow.setNextLocation",0,0);
				open(dir+list[i]);
				setLocation(0,0,width,height);
				close("\\Others");
				wait(checkImageTime);

				flagDetect = 1;
				if(lastModifiedTime > tempTime) tempTime = lastModifiedTime;
				
				sCount++;
				RECENT[sCount%5] = list[i];
			}
		}
	}
	if(flagDetect == 1) {
		zeroTime = tempTime;
		getDateAndTime(year0,month0,week0,day0,hour0,min0,sec0,msec0);
	}
	flagDetect = 0;
	wait(100);
}

showMessage("Time out");	


//-----------------------------------------------------------------------------

function pad2(n){
	n = toString(n);
	if(lengthOf(n) == 1) n="0"+n;
	return n;
}


//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

function fileExistInArray(fileName,ARRAY){
	output = 0;
	for(i=0;i<ARRAY.length;i++){
		if(ARRAY[i] == fileName) {
			output = 1;
			break;
		}
	}
	return output;
}

//-----------------------------------------------------------------------------

 

 

コードのざっくり説明

 

マクロ開始時の時間を取得し、これをファイル最終更新時間と比較して、新規ファイルを検出する」というシンプルなアルゴリズムです。

 

ファイルの最終更新時間を調べるために、File.lastModified(path)という命令を使っています。

このFile.lastModified(path)を実行すると、1970年1月1日午前0時0分から数えた時間である「UNIXTIME(単位はmsec)」が出力されます。

 

UNIXTIMEについてはこちらの記事を。

 

「UNIXTIME⇄普通の東京時間」で変換するのは面倒なので、『マクロ開始時にgetTimeを使うことで「マクロ開始UNIXTIME」を取得。これをディレクトリ内ファイルの「最終更新UNIXTIME」と比較する』という方法にしました。

 

マクロ開始UNIXTIME(zeroTime)は、新規ファイル検出時の最終更新UNIXTIMEで随時上書きしていくことで、継続して新規ファイルを検出することができます。

 

 

ちょっと脱線して、ややこしいけど大事な解説もしておきます。

getTime()で出力されるUNIXTIMEは「浮動小数点型の数値」、File.lastModifiedで出力されるUNIXTIMEは「文字列」となっています。

ImageJマクロでは、if内で比較を行う際に、「先に書いたモノの型」のルールで比較を行うっぽいです。つまり、if(文字列>数値)と書けば「文字列のルールで比較(昇順ソートで上か下か)」if(数値>文字列)と書けば「数値のルールで比較(数値として大きいか小さいか)」となります。

コード内のif(lastModifiedTime > zeroTime)のところで、文字列のルールで比較されてしまうと処理が狂ってしまいます。しかも多くの場合で、文字列の比較は求めていないはずです。そこでImageJ側が変な誤解をしないように、parseFloatを利用して、lastModifiedTimeを「浮動小数点の数値」として扱うように明確に指示しています。

 

 

以前のverとの比較

 

せっかくなので前回のデータベース分割式(ver.2)と今回のModifiedTime式(ver.3)と、で処理時間にどれぐらい変化が出るのかを調べてみました。 

 

 

比較の環境は、

・監視ディレクトリのファイル数は0個、214個、2172個、8100個、10272個の 5条件

・新規ファイルなしで、監視ループ処理を1回だけ回す

・データベース分割式はデータベース作成の時間を含む(毎回ループで更新される部分)

 

 

結果

 

 

 

データベース分割式では、ファイル数の二乗に比例して処理時間、つまり、画像表示までの遅延時間が長くなるようです。

 

データベース分割式では、ファイル数が10,272個では画像表示までの遅延時間が最大1.998秒かかることがわかりました。

 

Modified Time式では、ファイル数が10,272個でも遅延時間が最大0.252秒で表示できることがわかりました。

 

以上より、Modified Time式だと、遅延時間をかな〜り抑えることが出来るので、「安心して使える」ということがわかりました。

 

 

 

 

おしまい

 

 

 

 

imagej-jisui.hatenablog.com

 

 

 

 

ライセンスなんかは一切無いので、ぜひぜひ自由に使ってみてください!

 

imagej-jisui.hatenablog.com