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

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

【ImageJマクロ応用編】#2 複数の返り値を返すには

 

 

f:id:yu3xx:20211211012619p:plain

 

 

皆さまこんにちは。

yu3xx(ゆーさんちょめちょめ)です。

 

 

 ここまでのおさらい

 以前、「自作関数の作り方」の記事で、「return文」を使って「返り値を関数の外に返す方法」について解説しました。

 

return文の基本ルールは、「返り値は1つだけ」つまり「返り値は変数1つか配列1つだけ」です。

 

このルールのもとでは、

  return x,y;

  return x;

  return y;

などの書き方は無効です。

 


そこで今回は、「複数の返り値を返したい時の方法」について解説します。

 


もくじ

 

 

方法1. 返り値を配列にして、その中に2つの変数

例として、2つの数を引数にして、その2つの数の「足し算結果」と「引き算結果」をそれぞれ出力する関数を使います。

(100と25を引数にした場合、出力は125と75になります。)

 

以下のように、返り値とする配列の中に出力したい変数を格納しておくことで、2つ以上の変数を外に持ち出すことが出来ます。

function TashiHiki(a,b){
	ANS = newArray(2);
	ANS[0] = a + b;
	ANS[1] = a - b;
	return ANS;
}


X = TashiHiki(100,25);

Array.print(X);

f:id:yu3xx:20211211022904p:plain

方法2. グローバルな変数を受け皿として用意

通常、関数内で生まれた変数は、関数が終了すると消えてしまいます

 

そこで「var なにがし」あらかじめ用意しておいたグローバルな変数を受け皿として使うことで、「返り値のように」外に持ち出すことが出来ます。

 

この方法では「return文」は使いません!

var tashi, hiki;

function TashiHiki(a,b){
	tashi = a + b;
	hiki = a - b;
}


TashiHiki(100,25);

print(tashi, hiki);

f:id:yu3xx:20211211022954p:plain

方法3. グローバルな「配列」を受け皿として用意

グローバルな配列を用意して、複数の配列を外に持ち出すことも出来ます。

(この例ではあまり意味をなしませんが...)

var TASHI, HIKI;

function TashiHiki(a,b){
	TASHI = newArray(3);
	HIKI = newArray(3);
	TASHI[0] = a + b;
	HIKI[0] = a - b;
}


TashiHiki(100,25);

Array.print(TASHI);
Array.print(HIKI);

f:id:yu3xx:20211211023055p:plain

方法4.  引数は複数の配列、返り値も複数の配列

3のグローバルな配列を利用すると「引数を複数の配列に、返り値も複数の配列に」することが出来ます。

例として、配列Aと配列Bの「足し算結果」と「引き算結果」を出力します

var TASHI, HIKI;

function TashiHiki(X,Y){
	TASHI = newArray(X.length);
	HIKI = newArray(X.length);
	for(i=0; i<X.length; i++){
		TASHI[i] = X[i] + Y[i];
		HIKI[i] = X[i] - Y[i];
	}
}


A = newArray(100,200,300,400,500);
B = newArray(1,2,3,4,5);

TashiHiki(A,B);

Array.print(TASHI);
Array.print(HIKI);

f:id:yu3xx:20211211023200p:plain

グローバルな受け皿の注意点

グローバルな変数、配列を利用する方法だと「関数を呼び出すたびに結果が上書きされてしまう」という問題があります。

 

これを解消するために、関数を使って結果を出力するたびに「コピーして よけておく」という方法を取ります。

 

以下は配列を「値渡しコピー」して よけておく例です。

(参照渡しコピーと値渡しコピーについてはこちらのリンクから!)

var TASHI, HIKI;

function TashiHiki(X,Y){
	TASHI = newArray(X.length);
	HIKI = newArray(X.length);
	for(i=0; i<X.length; i++){
		TASHI[i] = X[i] + Y[i];
		HIKI[i] = X[i] - Y[i];
	}
}

//trial1
A = newArray(100,200,300,400,500);
B = newArray(1,2,3,4,5);

TashiHiki(A,B);
ANS1 = Array.copy(TASHI);
ANS2 = Array.copy(HIKI);

//trial2
C = newArray(10000,20000,30000,40000,50000);
D = newArray(1000,2000,3000,4000,5000);

TashiHiki(C,D);
ANS3 = Array.copy(TASHI);
ANS4 = Array.copy(HIKI);

//Results
Array.print(ANS1);
Array.print(ANS2);
Array.print(ANS3);
Array.print(ANS4);

f:id:yu3xx:20211211023255p:plain

おまけ

グローバルな配列を受け皿にした関数の例として、「フォルダ内全画像の縦横ピクセル数を、それぞれ配列に格納する」ためのマクロです。

var W,H;

showMessage("Select Open Folder");
openDir = getDirectory("Choose a Directory");
list = getFileList(openDir);

W = newArray(list.length);
H = newArray(list.length);


for(i=0; i<list.length; i++){
	open(openDir + list[i]);
	getWidthHeight(i);	
	close();
}

function getWidthHeight(i){
		w = getWidth();
		h = getHeight();
		W[i] = w;
		H[i] = h;
}

Array.print("W...",W);
Array.print("H...",H);

 

 

 

 

まとめ

 複数の返り値を返すためには

 

  方法① 返し値を配列にして、その中に結果を仕込む

     → 複数の「変数」を外に持ち出せる

  

  方法② return文を使わず、グローバルな受け皿に結果を入れる

    → 複数の「変数」や「配列」を外に持ち出せる 

 

 

 

 


おしまい

 

 

  

 

・公開したマクロのまとめ

imagej-jisui.hatenablog.com