最初から最後まで全く手を触れずに、コントラスト濃度変更処理などを実行することができるマクロです。
もくじ
コード
//PreInput Almighty.ijm
//based Almighty ver3.3.0
//ContrastAdjust (As necessary, for 8bit, FullColor)
//Optimize minAndMax (As necessary, Manual 3trials)
//Optimize minAndMaxAuto (As necessary)
//SetResolution (As necessary, for any Type)
//NombreCut type1 (As necessary, UseOneROI)
//NombreCut type2 (As necessary, CaseDivided by ODD/EVEN, [number==0 -> error])
//Renumbering from1 (As necessary, Files must be in subDirectory)
//Renumbering ATMT (As necessary, Automater, Only one trueTitle, trueTitle=pureTitle+kansuu)
//MakeDirAuto (FileName : trueTitle_pagenumber.ext)
//output txtFile (optMinMaxAuto)
//opDir no hitotsu sita no kaisou no directories ni SOREZORE "Almighty" wo kakeru
version = "4.1.0";
//1.2.0 -> hosei2
//1.3.0 -> enter cFiles
//2.0.0 -> Forced to proceed even if files are not in the subDirectory
//2.2.0 -> targetMeanBlack = 13 (optMinAndMaxAuto)
//3.0.0 -> pageCount
//3,1,0 -> pageCount%mabiki == 0
//3.2.0 -> xStep = 3*xSeg
//3.3.0 -> Sharpen
//3.4.0 -> }else if(procCount < cFiles){ ..... listFiles2
//3.5.0 -> run("Input/Output...", "jpeg=quality gif=-1 file=.csv copy_column copy_row save_column save_row");
//4.0.0 -> flagExtactRedChannel
//4.1.0 -> resize org.jpg (optMinMaxAuto)
print("");
print("Pre Input");
print("Almighty Processing");
print("ver",version);
print("makeDirAuto");
print("listFilesRecursively");
print("");
print("Subfolder Goto ni optMinMaxAuto");
print("Full Auto");
print("");
startTime = whatTimeNow();
//Select opDir
opDir=getDirectory("choose a directory");
listOp = getFileList(opDir);
print("opDir :",opDir);
//------------------------------------------
//Select Processing (enter 0 or 1)
flagContr = 1;
flagReso = 1;
flagNombre = 0;
flagSharpen = 1;
flagOptMinMaxAuto = 1;
flagOptMinMax = 0;
flagExtactRedChannel = 0;
flagRenumFrom1 = 0;
flagRenumATMT = 0;
//------------------------------------------
//------------------------------------------
//Enter Parameter
min = 0;
max =255;
flagFullColor = 0;
preDpi = 300;
postDpi = 400;
digit = 4;
output = "JPEG";
cFiles = 11;
hosei = -10; //adjust Max
hosei2 = 0; //adjust min, default=5 (targetMeanBlack=27),
//------------------------------------------
//Define variable
flagFullColor = 0;
var flagExtactRedChannel;
flagSave = 1;
flagOpenDir = 0;
var totalFiles = 0;
var procCount = 0;
var min;
var max;
var digit;
var compressionRate;
var ext;
var optimizedMin;
var optimizedMax;
var targetMeanWhite;
var targetMeanBlack;
var sumMin;
var sumMax;
var mabiki;
var OPT_MAX;
var OPT_MIN;
var cFiles;
var aCountMin;
var aCountMax;
var f;
var name;
var pageCount;
if(flagSave == 1){
saveDir = getDirectory("downloads");
print("Save to :",saveDir);
selectWindow("Log");
}
wait(1000);
//make parentDirectory
timeStamp = getTimeStamp();
parentDir = saveDir+"postProc_"+timeStamp+"/";
File.makeDirectory(parentDir);
//output txt (optMinMaxAuto)
if(flagOptMinMaxAuto == 1) {
outputTxt = saveDir + "postProc_"+timeStamp+".txt";
f = File.open(outputTxt);
}
//Loop START!!
for(m=0; m<listOp.length; m++){
openDir=opDir+listOp[m];
if(!endsWith(listOp[m],"/")) {
showMessageWithCancel("Found files that are NOT in the subDirectory. Check opDir. Do you wanna continue?");
openDir = opDir;
m = listOp.length + 1;//break after this loop
}
print("openDir:", openDir);
opeLoop();
}
//fin
finishTime = whatTimeNow();
print("Start Time .... ",startTime);
print("FinishTime ... ",finishTime);
print("oshimai");
beep();
//-----------------------------------------------------------------------------
//Define opeLoop
function opeLoop(){
totalFiles = 0;
procCount = 0;
//print flag
print("");
if(flagContr == 1) print("flagContr = ON");
if(flagReso == 1) print("flagReso = ON");
if(flagNombre == 1) print("flagNombre = ON");
if(flagSharpen == 1) print("flagSharpen = ON");
if(flagOptMinMax == 1) print("flagOptMinMax = ON");
if(flagOptMinMaxAuto == 1) print("flagOptMinMaxAuto = ON");
if(flagExtactRedChannel == 1) print("flagExtactRedChannel = ON");
if(flagRenumFrom1 == 1) print("flagRenumFrom1 = ON");
if(flagRenumATMT == 1) print("flagRenumATMT = ON");
//check flag
print("");
if(flagRenumFrom1 == 1 && flagRenumATMT == 1) exit("Two \"Renumbering Processing\" were selected.");
if(flagOptMinMax == 1 && flagOptMinMaxAuto == 1) exit("Two \"OptMinMax Processing\" were selected.");
if(flagFullColor == 1 && flagExtactRedChannel == 1) exit("flagFullColor and flagExtactRedChannel can't be used together");
if(flagOptMinMax == 1 || flagOptMinMaxAuto == 1){
if(flagContr == 0) print("Only optMinMax processing");
}
if(flagContr == 0 && flagReso == 0 && flagNombre == 0){
if(flagRenumFrom1 == 1 || flagRenumATMT == 1) print("Only Renumbering processing");
}
if(flagOptMinMax == 1 || flagOptMinMaxAuto == 1){
if(flagContr == 0 && flagReso == 0 && flagNombre == 0 && flagRenumFrom1 == 0 && flagRenumATMT == 0) {
flagSave = 0;
print("flagSave = OFF");
}
}
if(flagContr == 1 || flagReso == 1 || flagNombre == 1 || flagRenumFrom1 == 1 || flagRenumATMT == 1 || flagOptMinMaxAuto == 1){
flagOpenDir = 1;
}else{
print("flagOpenDir = OFF");
}
//Do something for selected folder
print("");
if(flagOpenDir == 1){
print("Processing :",openDir);
list = getFileList(openDir);
//count totalFiles
countFiles(openDir);
selectWindow("Log");
}
//Select Nombre Type
if(flagNombre == 1){
Dialog.create("Nombre Cut setting");
items = newArray("Use One ROI", "Case Divided by ODD/EVEN");
Dialog.addRadioButtonGroup("Select NombreCut Type", items, 2, 1, "Use One ROI");
Dialog.show;
nombreRadio = Dialog.getRadioButton();
if(nombreRadio == "Use One ROI") NombreType = 1;
if(nombreRadio== "Case Divided by ODD/EVEN") NombreType = 2;
}
//Clear ROI Manager and set ROI
if(flagNombre == 1){
roiCount = roiManager("count");
if(roiCount > 0){
roiManager("Deselect");
roiManager("Delete");
}
if(NombreType == 1){
//ROI setting
waitForUser("ROI setting","Open an image and set [ROI] using rectangle tool, then click [OK].");
roiManager("Add");
close();
}
if(NombreType == 2){
//ROI setting ODD(1,3,5,7,...)
waitForUser("ODD(1,3,5,7,...)","Open an [ODD number] file and set [ROI] using rectangle tool, then click [OK].");
roiManager("Add");
close();
//ROI setting EVEN(2,4,6,8,...)
waitForUser("EVEN(2,4,6,8,...)","Open an [EVEN number] file and set [ROI] using rectangle tool, then click [OK].");
roiManager("Add");
close();
}
}
//Enter parameter
if(flagSave == 1){
//print parameter
print("");
if(flagFullColor == 1) print("flagFullColor = ON");
if(flagOptMinMax == 0 && flagOptMinMaxAuto == 0){
if (flagContr == 1) print("min =",min,", Max =",max);
}
if (flagReso == 1) print("pre dpi =",preDpi,", Target dpi =",postDpi);
//Extension
if(output == "JPEG") ext = ".jpg";
if(output == "PNG") ext = ".png";
//JPEG,PNG quality setting(jpeg=90,gif=-1)
quality = 90;
run("Input/Output...", "jpeg=quality gif=-1 file=.csv copy_column copy_row save_column save_row");
if (output == "JPEG") print("JPEG quality =",quality);
print("");
}
//SetResolution Setting
if(flagReso == 1) compressionRate = postDpi/preDpi;
//Reference setting
var referLength;
if(flagRenumATMT == 1){
referenceCheck(openDir);
}
//optimizeMinAndMax
if(flagOptMinMax == 1) {
sumMin = 0;
sumMax = 0;
trials = 3;
OPT_MAX = newArray(trials);
OPT_MIN = newArray(trials);
for(now=0; now<trials; now++){
optMinMax(now,trials);
sumMin = sumMin + OPT_MIN[now];
sumMax = sumMax + OPT_MAX[now];
}
min = floor(sumMin/trials);
max = floor(sumMax/trials);
print("");
wait(1000);
for(i=0; i<trials; i++){
print(i+1,"...","min = ",OPT_MIN[i],", max = ",OPT_MAX[i]);
}
print("");
beep();
wait(1000);
print("Result...","optMin =",min,", optMax =",max);
wait(3000);
}
if(flagOptMinMaxAuto == 1) {
//Enter parameter
targetMeanWhite = 254.97;
targetMeanBlack = 13;
print("targetMeanWhite =",targetMeanWhite );
print("targetMeanBlack =",targetMeanBlack );
//mabiki = 60;
//Do something for selected folder
tempDir = saveDir + "Temp_optMinMax/";
print("Temp dir :",tempDir);
selectWindow("Log");
wait(1000);
//make tempDir
if(!File.exists(tempDir)){
File.makeDirectory(tempDir);
}
//Create Array
//cFiles = floor(totalFiles/mabiki);
cFiles = floor(cFiles);
mabiki = floor(totalFiles/cFiles);
if(mabiki < 1) exit("Error! Mottto cFiles Sukunaku.");
print("cFiles =",cFiles,", mabiki =",mabiki);
OPT_MAX = newArray(cFiles);
OPT_MIN = newArray(cFiles);
for(i=0; i<cFiles; i++){
OPT_MAX[i] = 0;
}
for(i=0; i<cFiles; i++){
OPT_MIN[i] = 255;
}
procCount = 0;
setBatchMode(true);
pageCount = 0;
listFiles2(openDir);
setBatchMode(false);
optMinMaxResults();
min = optimizedMin;
max = optimizedMax;
print("");
wait(1000);
print("acceptCount...min : ",aCountMin,", max : ",aCountMax);
beep();
wait(1000);
print("Result...","optMin =",min,", optMax =",max);
wait(3000);
}
//exit (only optMinMax)
if(flagSave == 0){
exit("oshimai");
}
//Renum from1
if (flagRenumFrom1 == 1){
Table.create("Correspondence Table");
}
//Main Operation
print("Now Operation...");
setBatchMode(true);
procCount = 0;
listFiles(openDir);
//clear ROI Manager
if(flagNombre == 1){
roiManager("Deselect");
roiManager("Delete");
}
//fin
if (flagRenumFrom1 == 1){
Table.update;
}
print("");
if(flagOptMinMax == 1){
for(i=0; i<trials; i++){
print(i+1,"...","min =",OPT_MIN[i],", max =",OPT_MAX[i]);
}
}
if(flagOptMinMaxAuto == 1) print("acceptCount...min : ",aCountMin,", max : ",aCountMax);
if(flagOptMinMax == 1 || flagOptMinMaxAuto == 1){
print("Result...","optMin =",min,", optMax =",max);
print("");
}
if (flagContr == 1) {
print("Contrast Adjust by...");
print("min =",min,", max =",max);
}
if (flagReso == 1) print("Compression Rate =",compressionRate);
if(flagSharpen == 1) print("Sharpen");
if (output == "JPEG") print("JPEG quality =",quality);
}//Fn_opeLoop End
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Define referenceCheck
function referenceCheck(dir){
list = getFileList(dir);
if(endsWith(list[0],"/")){
referenceCheck(dir+list[0]);
}else{
name = list[0];
dotIndex = lastIndexOf(name,".");
title = substring(name,0,dotIndex);
space = lastIndexOf(title," ");
trueTitle = substring(title,0,space);
number = substring(title,space+1);
reference = trueTitle;
referLength = lengthOf(reference);
selectWindow("Log");
print("Check trueTitle. (e.g. NARUTO_60)");
print("trueTitle=[",trueTitle,"]");
showMessageWithCancel("Check trueTitle (except : number.ext), and click [OK].");
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Define countFiles
function countFiles(dir){
list = getFileList(dir);
for(i=0; i<list.length; i++){
if(endsWith(list[i],"/")){
countFiles(dir+list[i]);
}else{
totalFiles++;
}
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Define listFiles
function listFiles(dir){
list = getFileList(dir);
for(i=0; i<list.length; i++){
if(endsWith(list[i],"/")){
listFiles(dir+list[i]);
}else{
open(dir+list[i]);
operation();
}
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Define listFiles2
//caution!! For optMinMaxAuto
function listFiles2(dir){
list = getFileList(dir);
for(i=0; i<list.length; i++){
if(endsWith(list[i],"/")){
listFiles2(dir+list[i]);
}else if(procCount < cFiles){
pageCount++;
if(pageCount % mabiki == 0){
open(dir+list[i]);
optMinMaxAuto();
}
}
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Define Main operation
function operation(){
procCount++;
//Progress.the second decimal place
//print(procCount,"/",totalFiles,"...Progress=",d2s(procCount/totalFiles*100,2),"%");
//Rename Section
if(flagRenumATMT == 1){
name = getTitle();
dotIndex = lastIndexOf(name,".");
title = substring(name,0,dotIndex);
//ReNumbering
titleLength = lengthOf(title);
if(referLength < titleLength){
space = lastIndexOf(title," ");
trueTitle = substring(title,0,space);
number = substring(title,space+1);
newname = trueTitle+"_"+zeroPad(number,digit)+ext;
}else if(referLength == titleLength){
newname = title+"_"+zeroPad(1,digit)+ext;
dotIndex = lastIndexOf(newname,".");
title = substring(newname,0,dotIndex);
underBar = lastIndexOf(title,"_");
trueTitle = substring(title,0,underBar);
number = substring(title,underBar+1);
}
}else if(flagRenumATMT == 0){
name = getTitle();
dotIndex = indexOf(name, ".");
title = substring(name,0,dotIndex);
underBar = lastIndexOf(title,"_");
trueTitle = substring(title,0,underBar);
number = substring(title,underBar+1);
newname = title+ext;
if (flagRenumFrom1 == 1) newname = trueTitle+"_"+zeroPad(i+1,digit)+ext;
}
rename(newname);
//Output Correspondence table
if (flagRenumFrom1 == 1){
Table.set("index",procCount-1,procCount);
Table.set("Original",procCount-1,name);
Table.set("Newname",procCount-1,newname);
}
//Nombre Cut
if(flagNombre == 1){
if(NombreType == 1){
roiManager("Select", 0);
run("Crop");
}
if(NombreType == 2){
number = parseInt(number);
if(number == 0) exit("Error!! Number must not be null.");
//ODD(1,3,5,7,...)
if(number%2 == 1){
roiManager("Select", 0);
run("Crop");
}
//EVEN(2,4,6,8,...)
if(number%2 == 0){
roiManager("Select", 1);
run("Crop");
}
}
}
//SetResolution
if (flagReso == 1){
width = getWidth;
height = getHeight;
targetW = floor(width*compressionRate);
run("Size...", "width=targetW constrain average interpolation=Bicubic");
}
//Filtering
if(flagSharpen == 1){
run("Sharpen");
// ---equiv--- //run("Convolve...", "text1=[-1 -1 -1\n-1 12 -1\n-1 -1 -1\n] normalize");
}
//ContrastAdjust 8 bit
depth = bitDepth();
if(flagFullColor == 0) {
if (depth == 8) {
//ContrastAdjust (As necessary)
if (flagContr == 1) setMinAndMax(min, max);
if (flagContr == 1) run("Apply LUT");
}
}
if(flagFullColor == 1) {
//ContrastAdjust (As necessary)
if (flagContr == 1) setMinAndMax(min, max);
if (flagContr == 1) run("Apply LUT");
}
if(flagExtactRedChannel == 1) {
//extract red channel to suppress yellowing
run("RGB Stack");
setSlice(1); //red stack
//ContrastAdjust
if (flagContr == 1) setMinAndMax(min, max);
if (flagContr == 1) run("Apply LUT", "stack");
}
//Save to SubDirectory
subDir = parentDir+trueTitle+"/";
if(!File.exists(subDir)){
File.makeDirectory(subDir);
}
if (flagContr == 0 && flagReso == 0 && flagNombre == 0) {
if(flagRenumFrom1 == 1 || flagRenumATMT == 1){
File.copy(dir+name,subDir+newname);
//print("Copy to...",subDir+newname);
}
}else{
saveAs(output, subDir+newname);
//print("Save to...",subDir+newname);
}
close(newname);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Define optMinMax
function optMinMax(now,trials){
print("");
print("OptimizeMinAndMax");
setBatchMode(false);
if(nImages == 0) waitForUser("OptMinAndMax. Open an image, then click [OK]");
//Enter parameter
if(now == 0){
Dialog.create("OptMinAndMax Setting");
Dialog.addNumber("targetMeanWhite",254.97);
Dialog.addNumber("targetMeanBlack",13); //default->18,27
Dialog.show;
targetMeanWhite = Dialog.getNumber();
targetMeanBlack = Dialog.getNumber();
}
if(flagExtactRedChannel == 1) {
run("RGB Stack");
setSlice(1); //red stack
updateDisplay();
}
name = getTitle();
tempDir = saveDir + "Temp_optMinMax/";
//make tempDir
if(!File.exists(tempDir)){
File.makeDirectory(tempDir);
}
saveAs("Jpeg", tempDir+"CheckMaxAndMin.jpg");
//optimize Max
setTool("rectangle");
run("Specify...", "width=100 height=100 x=10 y=10");
waitForUser("ROI selection","Set ROI on the \"WHITE BACK GROUND\", then click [OK].");
getStatistics(area,mean);
setBatchMode(true);
if(mean < 150){
exit("Error!! This area is not WHITE BACK GROUND.");
}
run("Crop");
saveAs("Jpeg", tempDir+"CheckMax.jpg");
close();
max = 254;
min = 0;
print("optimized Max Macro, TargetMean =",targetMeanWhite);
for (i=0; i<254; i++){
open(tempDir+"CheckMax.jpg");
setMinAndMax(min, max);
run("Apply LUT");
getStatistics(area,mean);
print("Max=",max," mean=",mean);
if(mean >= targetMeanWhite){
optimizedMax = max;
i = 255; //break
}
max = max-1;
close();
}
print("OptimizedMax =",optimizedMax);
setBatchMode(false);
//optimize min
open(tempDir+"CheckMaxAndMin.jpg");
setTool("rectangle");
run("Specify...", "width=100 height=100 x=10 y=10");
waitForUser("ROI selection","Set ROI on the \"BLACK ZONE\", then click [OK].");
getStatistics(area,mean);
setBatchMode(true);
if(mean > 100){
exit("Error!! This area is not BLACK ZONE.");
}
run("Crop");
saveAs("Jpeg", tempDir+"CheckMin.jpg");
close();
max = optimizedMax;
min = 1;
print("");
print("OptimizedMin Macro, TargetMean=",targetMeanBlack);
for (i=0; i<254; i++){
open(tempDir+"CheckMin.jpg");
setMinAndMax(min, max);
run("Apply LUT");
getStatistics(area,mean);
print("min=",min," mean=",mean);
if(mean <= targetMeanBlack){
optimizedMin = min;
i=255; //break
}
min = min+1;
close();
}
//Results
OPT_MIN[now] = optimizedMin;
OPT_MAX[now] = optimizedMax;
print("");
print(now+1,"/",trials);
print("Title =",name);
print("OptimizedMin =",optimizedMin);
print("OptimizedMax =",optimizedMax);
setBatchMode(false);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Define optMinMaxAuto
function optMinMaxAuto(){
name = getTitle();
//Progress
print("");
print(procCount+1, "/", cFiles, "...Progress=",d2s(procCount/cFiles*100,2),"%" , " [OptMinMaxAuto]");
print("pageCount = ", pageCount);
print("...",name);
if(flagExtactRedChannel == 1) {
run("RGB Stack");
setSlice(1); //red stack
updateDisplay();
}
depth = bitDepth();
if (depth == 8) {
run("Size...", "width=400 depth=1 constrain average interpolation=Bilinear");
saveAs("Jpeg", tempDir+"org.jpg");
width = getWidth();
height = getHeight();
x = 0;
y = 0;
sum = 0;
whiteCheckCount = 0;
blackCheckCount = 0;
whiteSegCount = 0;
blackSegCount = 0;
whiteMax = 0;
blackMin = 255;
//whiteBackGround
segCount = 0;
xSeg = 10;
ySeg = 10;
xStep = xSeg;
yStep = ySeg;
for(x=0; x<width-xSeg; x=x+xStep){
for(xi=0; xi<xSeg; xi++){
for(yi=0; yi<ySeg; yi++){
pixelValue = getPixel(x+xi,y+yi);
sum = sum+pixelValue;
}
}
mean = sum/xSeg/ySeg;
if(mean > whiteMax) {
whiteMax = mean;
whiteSegCount = segCount;
whiteCheckCount++;
//print("ImgNo.",procCount+1, ", white-",whiteCheckCount);
}
makeRectangle(x, y, xSeg, ySeg);
run("Crop");
saveTitle = "wSegNo"+zeroPad(segCount,6);
saveAs("Jpeg", tempDir+saveTitle+".jpg");
close();
open(tempDir+"org.jpg");
sum = 0;
segCount++;
}
//blackKuroBeta
segCount = 0;
xSeg = 8;
ySeg = 8;
xStep = 2*xSeg;
yStep = 2*ySeg;
for(y=0; y<height-ySeg; y=y+yStep){
for(x=0; x<width-xSeg; x=x+xStep){
for(xi=0; xi<xSeg; xi++){
for(yi=0; yi<ySeg; yi++){
pixelValue = getPixel(x+xi,y+yi);
sum = sum+pixelValue;
}
}
mean = sum/xSeg/ySeg;
if(mean < blackMin){
blackMin = mean;
blackSegCount = segCount;
blackCheckCount++;
//print("ImgNo.",procCount+1, ", black-",blackCheckCount);
}
makeRectangle(x, y, xSeg, ySeg);
run("Crop");
saveTitle = "bSegNo"+zeroPad(segCount,6);
saveAs("Jpeg", tempDir+saveTitle+".jpg");
close();
open(tempDir+"org.jpg");
sum = 0;
segCount++;
}
}
close("org.jpg"); //originalImage
//checkMax Loop
optimizedMax = 0; //If not found
max = 254;
min = 0;
print("Checking Max..." , "wSegNo" + zeroPad(whiteSegCount,6) + ".jpg");
for (i=0; i<254; i++){
open(tempDir+"wSegNo"+zeroPad(whiteSegCount,6)+".jpg");
setMinAndMax(min, max);
run("Apply LUT");
getStatistics(area,mean);
if(mean >= targetMeanWhite){
optimizedMax = max;
i = 255; //break
}
max = max-1;
// print(min,max,mean);
// print("Checking Max..." , "wSegNo" + zeroPad(whiteSegCount,6) + ".jpg");
close();
}
print("Temp_OptimizedMax =",optimizedMax);
OPT_MAX[procCount] = optimizedMax;
//checkMin Loop
optimizedMin = 255; //If not found
max = 220; //Daitai 200 Gurai Ooi kara
min = 1;
print("Checking Min..." , "bSegNo" + zeroPad(blackSegCount,6) + ".jpg");
for (i=0; i<254; i++){
open(tempDir+"bSegNo"+zeroPad(blackSegCount,6)+".jpg");
setMinAndMax(min, max);
run("Apply LUT");
getStatistics(area,mean);
if(mean <= targetMeanBlack){
optimizedMin = min;
i=255; //break
}
min = min+1;
// print(min,max,mean);
// print("Checking Min..." , "bSegNo" + zeroPad(blackSegCount,6) + ".jpg");
if(min == max){
i=255; //break
}
close();
}
print("Temp_OptimizedMin =",optimizedMin);
OPT_MIN[procCount] = optimizedMin;
}else{ //else if(depth != 8bit)
close(name); //original Image
}
procCount++; //and back to listFiles2
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Define optMinMaxResults
function optMinMaxResults(){
// //Plot Graphs
// i=linspace(1,cFiles,cFiles);
// Plot.create("Max","No.","Max",i,OPT_MAX);
// Plot.show();
// Plot.create("Min","No.","Min",i,OPT_MIN);
// Plot.show();
//Max
aCountMax=0;
//Outlier Exclusion
for(i=0; i<cFiles; i++){
if(OPT_MAX[i] > 150){
aCountMax++;
}
}
if(aCountMax == 0) exit("Error! Mabiki motto sukunaku.");
OPT_MAX = bubbleSort(OPT_MAX);
OPT_MAX = Array.slice(OPT_MAX,cFiles-aCountMax,cFiles);
median = floor(aCountMax/2);
if(aCountMax % 2 == 0) median = median-1;
optimizedMax = OPT_MAX[median] + hosei;
//Min
aCountMin=0;
for(i=0; i<cFiles; i++){
if(OPT_MIN[i] < 100){
aCountMin++;
}
}
if(aCountMin == 0) exit("Error! Mabiki motto sukunaku.");
OPT_MIN = bubbleSort(OPT_MIN);
OPT_MIN = Array.slice(OPT_MIN,0,aCountMin);
median = floor(aCountMin/2);
if(aCountMin % 2 == 0) median = median-1;
optimizedMin = OPT_MIN[median] + hosei2;
//Results
print("");
print("OPT_MIN = ");
Array.print(OPT_MIN);
print("OPT_MAX = ");
Array.print(OPT_MAX);
print("OptimizedMin =",optimizedMin);
print("OptimizedMax =",optimizedMax);
//output txt
print(f, name + "\t" + "optMin = " + optimizedMin + "\t" + "optMax = " + optimizedMax + "\t" + "acceptCount (min, max) = " + aCountMin + ", " + aCountMax);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Define function getTimeStamp
function getTimeStamp(){
getDateAndTime(year,month,dayOfWeek,dayOfMonth,hour,minute,second,msec);
timeStamp = "string";
strYear = ""+year;
month = month+1;
if(month < 10){
strMonth = "0"+month;
}else{
strMonth = ""+month;
}
if(dayOfMonth < 10){
strDayOfMonth = "0"+dayOfMonth;
}else{
strDayOfMonth = ""+dayOfMonth;
}
if(hour < 10){
strHour = "0"+hour;
}else{
strHour = ""+hour;
}
if(minute < 10){
strMinute = "0"+minute;
}else{
strMinute = ""+minute;
}
if(second < 10){
strSecond = "0"+second;
}else{
strSecond = ""+second;
}
timeStamp = strYear+strMonth+strDayOfMonth+"_"+strHour+"h"+strMinute+"m"+strSecond+"s";
return timeStamp;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Define function whatTimeNow
function whatTimeNow(){
getDateAndTime(year,month,dayOfWeek,dayOfMonth,hour,minute,second,msec);
stringTime = "string";
strYear = ""+year;
month = month+1;
if(month < 10){
strMonth = "0"+month;
}else{
strMonth = ""+month;
}
if(dayOfMonth < 10){
strDayOfMonth = "0"+dayOfMonth;
}else{
strDayOfMonth = ""+dayOfMonth;
}
if(hour < 10){
strHour = "0"+hour;
}else{
strHour = ""+hour;
}
if(minute < 10){
strMinute = "0"+minute;
}else{
strMinute = ""+minute;
}
if(second < 10){
strSecond = "0"+second;
}else{
strSecond = ""+second;
}
stringTime = strYear+"/"+strMonth+"/"+strDayOfMonth+"_"+strHour+":"+strMinute+":"+strSecond;
return stringTime;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Define function zeroPadding
function zeroPad(int,digitZeroPad){
if(int < 0){
exit("ZeroPadding Error!! int<0");
}
stringInt = ""+int;
digitStringInt = lengthOf(stringInt);
digitSubtra = digitZeroPad-digitStringInt;
if(digitSubtra < 0){
exit("ZeroPadding Error!! digitSubtra<0");
}
if(digitZeroPad > 0){
for(i=0; i<digitSubtra; i++){
stringInt = "0"+stringInt;
}
}
return stringInt;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Define function linspace (generate Arithmetric Sequence)
//a->1st term, an->last term, n->term number
function linspace(a,an,n){
A = newArray(n);
d = (an-a)/(n-1);
for(i=0;i<n;i++){
A[i] = a+i*d;
}
return A;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Define function bubble_sort
function bubbleSort(A){
n=A.length;
for(i=0;i<n-1;i++){
for(j=n-1;j>i;j--){
if(A[j]<A[j-1]){
tmp=A[j];
A[j]=A[j-1];
A[j-1]=tmp;
}
}
}
return A;
}
//-----------------------------------------------------------------------------
ポイント
基本的には多目的自炊マクロ「Almighty Processing ver.3」のアレンジ版です。
今までと違うのは
① 起動後のダイアログを極力排除して、起動したら終わるまで何もしなくてOK!
② 保存先フォルダをPC内の「ダウンロード先フォルダ」に設定したので、いちいち選ばなくてOK!
③ 選択した処理フォルダの1つ下の階層のフォルダごとに「Almighty Processing」をかけるイメージなので、コントラスト濃度変更の「Min, Max」が独立別個!
④ 解析結果の最適Min Max値をtxtファイルにして書き出し!
プログラムコード内の値を直接いじることで処理内容を決定しているので、ちょっと上級者むけですが、
寝てる間にドカっとまとめて処理したい!
って時におすすめです。
基本的に、optMinMaxAutoで自動解析した後に、Contrasut Adjustmentでコントラスト・濃度を変更する用に作っています。
なので他の処理を噛ませた時のデバッグはしていないのでご注意を。
使い分け
① 1タイトルだけが対象で、自分の目でカクニンしながら確実に最適なMin, Maxでコントラスト濃度変更したい時
→「Almighty Processing ver.3」で「Optimize MinAndMax (Manual)」
【真・改良版】コントラスト調整やリサイズ処理などなどを、一気にやってしまうためのMacro - その漫画自炊オタクはImageJマクロに恋をする
② 複数タイトルが対象で、1タイトルずつMin, Maxを調べるのがメンドウなのでまとめて一気に自動処理させたい時
→本記事の「Pre Input Almighty」で「Optimize MinAndMax (Auto)」
デフォルトの処理内容
0がオフで、1がオンです。このあたりをいじって処理内容を変更してください。
//Select Processing (enter 0 or 1)
flagContr = 1;
flagReso = 0;
flagNombre = 0;
flagOptMinMaxAuto = 1;
flagOptMinMax = 0;
flagRenumFrom1 = 1;
flagRenumATMT = 0;
各パラメータも基本的にダイアログではなく、あらかじめ打ち込んでおくタイプなので、コード内を探して変更してください。
(解像度変更の設定dpiとか)
保存先フォルダは、とりあえずどんなPCでも動作する(はず)なので「ダウンロード先フォルダ」にしています。
自分の好きな場所に変更すると、より使いやすいと思います。
各機能の解説
各処理の細かな解説は、以下のページを参考にしてみてください。
・Contrast Adjustment
コントラスト・濃度を調整するMacro - その漫画自炊オタクはImageJマクロに恋をする
・Optimize Min And Max [Manual]
コントラスト調整に必要なMax値とMin値を自動で求めるためのMacro - その漫画自炊オタクはImageJマクロに恋をする
・Change the Resolution
解像度を変更するMacro - その漫画自炊オタクはImageJマクロに恋をする
・Nombre Cut
実用版!ノンブル領域を削除し, コントラスト調整, 解像度変更も一括で行えるMacro - その漫画自炊オタクはImageJマクロに恋をする
・Renumbering [from 1]
【多目的】コントラスト調整やリサイズ処理などなどを、一気にやってしまうためのMacro - その漫画自炊オタクはImageJマクロに恋をする
・Renumbering [Automator]
【Mac】実用版!PDFからJPEGに変換した画像のコントラスト調整+フォルダ収納のためのMacro - その漫画自炊オタクはImageJマクロに恋をする
ライセンスなんかは一切無いので、ぜひぜひ自由に使ってみてください!