Added Settingsfile & Minor Code cleanup

A settings.txt file is created and filled with
the hard-coded values if none is found.
If one is found its content will overwrite the
hard-coded values.

Checks if the internal version string matches the settings.txt
file before loading the values.
The settings file ignores lines not matching the regex: ".*=.*"
dev
Peery 7 years ago
parent a873a0e096
commit 06691c653a

@ -1,31 +1,37 @@
package peery; package peery;
import java.io.File; import java.io.File;
import java.util.HashMap;
import peery.file.FileHandler; import peery.file.FileHandler;
import peery.file.SettingsHandler;
import peery.log.Log; import peery.log.Log;
import peery.log.LogLevel; import peery.log.LogLevel;
import peery.picture.ImageAnalyzer; import peery.picture.ImageAnalyzer;
import peery.picture.ImageUtils;
public class Mosaic extends Thread{ public class Mosaic extends Thread{
public static final String programmName = "Mosaic", public static final String programmName = "Mosaic",
versionString = "Alpha-0.33"; versionString = "Alpha-0.40";
private static final String outputName = "Output"; private static String outputName = "Output";
private static final int gridX = 100, gridY = 50, targetMulti = 2, private static int gridWidth = 100, gridHeight = 100, targetMulti = 2,
alphaThreshhold = 30, alphaThreshhold = 30,
adaptionCount = 300, adaptionCount = 300,
inputWorkerLimit = 10, inputWorkerLimit = 10,
targetWorkerLimit = 4, targetWorkerLimit = 8,
matchWorkerLimit = 10, matchWorkerLimit = 10,
placeWorkerLimit = 2; placeWorkerLimit = 2; //get overwritten by file settings
private static final double adaptionStep = 1.1, gridErrorThresh = 0.15; private static double adaptionStep = 1.1, gridErrorThresh = 0.15;
private static boolean keepRatio = false; private static boolean keepRatio = true, overlapImages = true;
/* /*
* *
* Performance: * TO DO:
* Write down stats what image was used (how often)
* Make settings save & load from a settings file
* *
* Performance:
* *
* FIX: * FIX:
* rasterization doesn't cover everything! * rasterization doesn't cover everything!
@ -36,6 +42,7 @@ public class Mosaic extends Thread{
* explore guarantee of usage of at least once, each image. * explore guarantee of usage of at least once, each image.
*/ */
public SettingsHandler sh;
public FileHandler fh; public FileHandler fh;
public ImageAnalyzer ia; public ImageAnalyzer ia;
@ -43,17 +50,26 @@ public class Mosaic extends Thread{
fh = new FileHandler("resources"); fh = new FileHandler("resources");
Log.log(LogLevel.Info, "Starting "+programmName+" "+versionString); Log.log(LogLevel.Info, "Starting "+programmName+" "+versionString);
ia = new ImageAnalyzer(fh, inputWorkerLimit, targetWorkerLimit, matchWorkerLimit, ia = new ImageAnalyzer(fh, inputWorkerLimit, targetWorkerLimit, matchWorkerLimit,
placeWorkerLimit, alphaThreshhold, keepRatio); placeWorkerLimit, alphaThreshhold, keepRatio, overlapImages);
sh = new SettingsHandler(fh, "settings.txt");
this.start(); this.start();
} }
public void run(){ public void run(){
Log.log.perfLog("Started "+programmName+" v."+versionString); Log.log.perfLog("Started "+programmName+" v."+versionString);
Log.log(LogLevel.Info, "Checking for settings file ...");
if(sh.settingsFile.exists()){
Log.log(LogLevel.Info, "Importing settings from file ...");
importSettings(sh.loadSettings());
}else{
Log.log(LogLevel.Info, "Couldn't find a settings file. Dumping hard-coded settings ...");
sh.saveSettings(exportSettings());
}
System.out.println("gridHeightxxx:"+gridHeight);
Log.log.perfLog("Starting indexing ..."); Log.log.perfLog("Starting indexing ...");
prepMatching(); prepMatching();
//Log.log(LogLevel.Error, ia.slotClassifications.toString()+" prep:"+ia.isPrepInProgress());
//Log.log(LogLevel.Error, ia.slotClassifications.toString()+" prep:"+ia.isPrepInProgress());
while(ia.isPrepInProgress()){ while(ia.isPrepInProgress()){
try { try {
@ -82,13 +98,14 @@ public class Mosaic extends Thread{
e.printStackTrace(); e.printStackTrace();
} }
} }
cutOutGrid(); ImageUtils.cutOutGrid(ia);
Log.log.perfLog("Finished Placement!"); Log.log.perfLog("Finished Placement!");
Log.log(LogLevel.Info, "Finished placement. Output is done ..."); Log.log(LogLevel.Info, "Finished placement. Output is done ...");
Log.log.perfLog("Saving output to file ..."); Log.log.perfLog("Saving output to file ...");
fh.saveImage(ia.canvas, new File(fh.OutputFolder+fh.fs+outputName+"-"+fh.OutputFolder.listFiles().length+".png")); fh.saveImage(ia.canvas, new File(fh.OutputFolder+fh.fs+outputName+"-"+fh.OutputFolder.listFiles().length+".png"));
Log.log.perfLog("Everything done! Exiting ..."); Log.log.perfLog("Everything done! Exiting ...");
Log.log.finishPerfLog(); Log.log.finishPerfLog();
Log.shutdownLog();
} }
/** /**
@ -97,7 +114,7 @@ public class Mosaic extends Thread{
* Starts threads to index all not indexed images and rasterizes and classifies the Target. * Starts threads to index all not indexed images and rasterizes and classifies the Target.
*/ */
public void prepMatching(){ public void prepMatching(){
ia.rasterizeTarget(gridX, gridY, targetMulti, gridErrorThresh, adaptionCount, adaptionStep); ia.rasterizeTarget(gridWidth, gridHeight, targetMulti, gridErrorThresh, adaptionCount, adaptionStep);
ia.updateIndex(); ia.updateIndex();
ia.classifyTarget(); ia.classifyTarget();
} }
@ -112,10 +129,47 @@ public class Mosaic extends Thread{
ia.placeFragments(); ia.placeFragments();
} }
public void cutOutGrid(){ public void importSettings(HashMap<String, String> settings){
Log.log(LogLevel.Info, "Cutting out what the grid covered!"); if(0 < settings.get("version").compareTo(versionString)){
Log.log(LogLevel.Debug, "Cutting out 0 0 "+ia.gridEnd[0]+" "+ia.gridEnd[1]); Log.log(LogLevel.Error, "Won't import settings! Version String doesn't match!");
ia.canvas = ia.canvas.getSubimage(0, 0, ia.gridEnd[0], ia.gridEnd[1]); Log.log(LogLevel.Error, "Read: "+versionString+" Expected: "+settings.get("version"));
return;
}
outputName = settings.get("outputName");
gridWidth = Integer.parseInt(settings.get("gridWidth"));
gridHeight = Integer.parseInt(settings.get("gridHeight"));
targetMulti = Integer.parseInt(settings.get("targetMultiplier"));
alphaThreshhold = Integer.parseInt(settings.get("alphaThreshhold"));
adaptionCount = Integer.parseInt(settings.get("adaptionCount"));
inputWorkerLimit = Integer.parseInt(settings.get("inputWorkerLimit"));
targetWorkerLimit = Integer.parseInt(settings.get("targetWorkerLimit"));
matchWorkerLimit = Integer.parseInt(settings.get("matchWorkerLimit"));
placeWorkerLimit = Integer.parseInt(settings.get("placeWorkerLimit"));
adaptionStep = Double.parseDouble(settings.get("adaptionStep"));
gridErrorThresh = Double.parseDouble(settings.get("gridErrorThresh"));
keepRatio = Boolean.parseBoolean(settings.get("keepRatio"));
overlapImages = Boolean.parseBoolean(settings.get("overlapImages"));
}
public HashMap<String, String> exportSettings(){
HashMap<String, String> settings = new HashMap<String, String>();
settings.put("version", versionString);
settings.put("outputName", outputName);
settings.put("gridWidth", Integer.toString(gridWidth));
settings.put("gridHeight", Integer.toString(gridHeight));
settings.put("targetMultiplier", Integer.toString(targetMulti));
settings.put("alphaThreshhold", Integer.toString(alphaThreshhold));
settings.put("adaptionCount", Integer.toString(adaptionCount));
settings.put("inputWorkerLimit", Integer.toString(inputWorkerLimit));
settings.put("targetWorkerLimit", Integer.toString(targetWorkerLimit));
settings.put("matchWorkerLimit", Integer.toString(matchWorkerLimit));
settings.put("placeWorkerLimit", Integer.toString(placeWorkerLimit));
settings.put("adaptionStep", Double.toString(adaptionStep));
settings.put("gridErrorThresh", Double.toString(gridErrorThresh));
settings.put("keepRatio", Boolean.toString(keepRatio));
settings.put("overlapImages", Boolean.toString(overlapImages));
return settings;
} }
public static void main(String[] args){ public static void main(String[] args){

@ -213,6 +213,23 @@ public class FileHandler {
return indexData; return indexData;
} }
public void overwriteIndex(HashMap<String, Integer> index){
try{
BufferedWriter bw = new BufferedWriter(new FileWriter(indexFile, false));
for(String key: index.keySet()){
bw.write(index.get(key)+";"+key+"\n");
}
bw.flush();
bw.close();
Log.log(LogLevel.Info, "Overwrote index file with new index!");
} catch (IOException e) {
Log.log(LogLevel.Critical, "Couldn't create or write index file "+indexFile.getAbsolutePath()+" ."
+ "Are write permissions missing?");
e.printStackTrace();
return;
}
}
/** /**
* Parses a line of indexData into an ArrayList containing the rgb int and the name * Parses a line of indexData into an ArrayList containing the rgb int and the name
* @param indexData * @param indexData

@ -0,0 +1,70 @@
package peery.file;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Scanner;
import peery.log.Log;
import peery.log.LogLevel;
public class SettingsHandler {
public File settingsFile;
public SettingsHandler(FileHandler fh, String settings){
this.settingsFile = new File(fh.sourceFolder.getAbsolutePath()+fh.fs+settings);;
}
/**
* Saves the settings to file.
* @param settings
*/
public void saveSettings(HashMap<String, String> settings){
try {
Log.log(LogLevel.Info, "Saving settings to file ...");
BufferedWriter bw = new BufferedWriter(new FileWriter(settingsFile, false));
for(String key: settings.keySet()){
bw.write(key+"="+settings.get(key)+"\n");
bw.flush();
}
bw.close();
} catch (IOException e) {
Log.log(LogLevel.Error, "Couldn't write settings file at "+settingsFile.getAbsolutePath()+" ! Are write permissions missing?");
e.printStackTrace();
}
}
/**
* Loads all settings from file.
* @return
*/
public HashMap<String, String> loadSettings(){
HashMap<String, String> settings;
try {
settings = new HashMap<String, String>();
Scanner sc = new Scanner(new BufferedReader(new FileReader(settingsFile)));
while(sc.hasNext()){
String raw = sc.nextLine();
if(!raw.matches(".*=.*")){
continue;
}
String[] entry = raw.split("=");
//System.out.println(entry[0]+":"+entry[1]);
settings.put(entry[0], entry[1]);
}
sc.close();
return settings;
} catch (FileNotFoundException e) {
Log.log(LogLevel.Error, "Couldn't load settings file at "+settingsFile.getAbsolutePath()+" ! Are read permissions missing?");
e.printStackTrace();
}
return null;
}
}

@ -11,7 +11,7 @@ import peery.file.FileHandler;
public class Log { public class Log {
public static Log log; public static Log log;
public static final boolean silenceDebug = false, public static final boolean silenceDebug = true,
appendEvents = false, appendErrors = false; appendEvents = false, appendErrors = false;
private final static String readmeText = private final static String readmeText =
@ -73,6 +73,7 @@ public class Log {
try { try {
Log.log.errorWriter.close(); Log.log.errorWriter.close();
Log.log.eventWriter.close(); Log.log.eventWriter.close();
Log.log.perfWriter.close();
Log.log = null; Log.log = null;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

@ -29,7 +29,7 @@ public class ImageAnalyzer {
private HashMap<String, Integer> index; private HashMap<String, Integer> index;
private int alphaThreshhold; private int alphaThreshhold;
public final boolean keepRatio; public final boolean keepRatio, overlapImages;
public int[] gridEnd; public int[] gridEnd;
//Input Classification Worker //Input Classification Worker
@ -59,11 +59,13 @@ public class ImageAnalyzer {
// //
public ImageAnalyzer(FileHandler fh, int inputWorkersLimit, int targetWorkersLimit, public ImageAnalyzer(FileHandler fh, int inputWorkersLimit, int targetWorkersLimit,
int matchWorkersLimit, int placeWorkersLimit, int alphaThreshhold, boolean keepRatio){ int matchWorkersLimit, int placeWorkersLimit, int alphaThreshhold, boolean keepRatio,
boolean overlapImages){
this.fh = fh; this.fh = fh;
this.target = fh.loadImage(fh.TargetImageFile); this.target = fh.loadImage(fh.TargetImageFile);
this.alphaThreshhold = alphaThreshhold; this.alphaThreshhold = alphaThreshhold;
this.keepRatio = keepRatio; this.keepRatio = keepRatio;
this.overlapImages = overlapImages;
this.gridEnd = new int[2]; this.gridEnd = new int[2];
this.inputWorkersLimit = inputWorkersLimit; this.inputWorkersLimit = inputWorkersLimit;
@ -335,7 +337,8 @@ public class ImageAnalyzer {
Log.log(LogLevel.Debug, "Target will be "+(int)(targetSize.width*targetSizeMultiplier) Log.log(LogLevel.Debug, "Target will be "+(int)(targetSize.width*targetSizeMultiplier)
+"x"+(int)(targetSize.height*targetSizeMultiplier)+" big."); +"x"+(int)(targetSize.height*targetSizeMultiplier)+" big.");
Log.log(LogLevel.Debug, "Slots are "+preSlotWidth+"x"+preSlotHeight+" big."); Log.log(LogLevel.Debug, "Slots on the Target are "+preSlotWidth+"x"+preSlotHeight+" big.");
Log.log(LogLevel.Debug, "Slots on the Output are "+postSlotWidth+"x"+postSlotHeight+" big.");
slotX = gridX; slotX = gridX;
slotY = gridY; slotY = gridY;
slotCount = gridX*gridY; slotCount = gridX*gridY;

@ -5,30 +5,51 @@ import java.awt.Graphics2D;
import java.awt.Image; import java.awt.Image;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import peery.log.Log;
import peery.log.LogLevel;
public class ImageUtils { public class ImageUtils {
public static BufferedImage resizeImage(BufferedImage input, Dimension targetSize, boolean keepRatio){ private static final int scalingMethod = Image.SCALE_SMOOTH;
/**
* TODO Needs cleanup
* @param input
* @param targetSize
* @param keepRatio
* @param overlapImages
* @return
*/
public static BufferedImage resizeImage(BufferedImage input, Dimension targetSize, boolean keepRatio,
boolean overlapImages){
Image tmp; Image tmp;
BufferedImage img; BufferedImage img;
int imageWidth, imageHeight;
if(!keepRatio){ if(!keepRatio){
tmp = input.getScaledInstance((int)targetSize.getWidth(), (int)targetSize.getHeight(), Image.SCALE_SMOOTH); imageWidth = (int)targetSize.getWidth();
img = new BufferedImage(tmp.getWidth(null), tmp.getHeight(null), BufferedImage.TYPE_INT_ARGB); imageHeight = (int)targetSize.getHeight();
Graphics2D g2 = (Graphics2D) img.getGraphics();
g2.drawImage(tmp, 0, 0, null);
g2.dispose();
return img;
} }
else{
if(!overlapImages){
if(input.getWidth() > input.getHeight()){ if(input.getWidth() > input.getHeight()){
tmp = input.getScaledInstance((int)targetSize.getWidth(), -1, Image.SCALE_SMOOTH); imageWidth = (int)targetSize.getWidth();
img = new BufferedImage(tmp.getWidth(null), tmp.getHeight(null), BufferedImage.TYPE_INT_ARGB); imageHeight = -1;
Graphics2D g2 = (Graphics2D) img.getGraphics();
g2.drawImage(tmp, 0, 0, null);
g2.dispose();
return img;
}else{ }else{
tmp = input.getScaledInstance(-1, (int)targetSize.getHeight(), Image.SCALE_SMOOTH); imageWidth = -1;
imageHeight = (int)targetSize.getHeight();
}
}else{
if(input.getWidth() < input.getHeight()){
imageWidth = (int)targetSize.getWidth();
imageHeight = -1;
}else{
imageWidth = -1;
imageHeight = (int)targetSize.getHeight();
}
}
}
tmp = input.getScaledInstance(imageWidth, imageHeight, scalingMethod);
img = new BufferedImage(tmp.getWidth(null), tmp.getHeight(null), BufferedImage.TYPE_INT_ARGB); img = new BufferedImage(tmp.getWidth(null), tmp.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = (Graphics2D) img.getGraphics(); Graphics2D g2 = (Graphics2D) img.getGraphics();
@ -36,6 +57,11 @@ public class ImageUtils {
g2.dispose(); g2.dispose();
return img; return img;
} }
public static void cutOutGrid(ImageAnalyzer ia){
Log.log(LogLevel.Info, "Cutting out what the grid covered!");
Log.log(LogLevel.Debug, "Cutting out 0 0 "+ia.gridEnd[0]+" "+ia.gridEnd[1]);
ia.canvas = ia.canvas.getSubimage(0, 0, ia.gridEnd[0], ia.gridEnd[1]);
} }
/** /**

@ -26,12 +26,12 @@ public class PlacementWorker extends ImageAnalyzerWorker{
public void run() { public void run() {
Log.log(LogLevel.Info, "Worker "+this.getName()+" commencing work!"); Log.log(LogLevel.Info, "Worker "+this.getName()+" commencing work!");
for(File file: coordMap.keySet()){ for(File file: coordMap.keySet()){
if(coordMap.get(file) == null){ if(coordMap.get(file) == null){ //Check to avoid NullPointerException
continue; continue;
} }
BufferedImage img = ia.fh.loadImage(file); BufferedImage img = ia.fh.loadImage(file);
ArrayList<int[]> coords = coordMap.get(file); ArrayList<int[]> coords = coordMap.get(file);
img = ImageUtils.resizeImage(img, new Dimension(ia.postSlotWidth, ia.postSlotHeight), ia.keepRatio); img = ImageUtils.resizeImage(img, new Dimension(ia.postSlotWidth, ia.postSlotHeight), ia.keepRatio, ia.overlapImages);
Log.log(LogLevel.Debug, "["+this.getName()+"] Resized image "+file.getName()+" to "+img.getWidth()+"x"+img.getHeight()+" !"); Log.log(LogLevel.Debug, "["+this.getName()+"] Resized image "+file.getName()+" to "+img.getWidth()+"x"+img.getHeight()+" !");
Log.log(LogLevel.Info, "["+this.getName()+"] Going to place \""+file.getName()+"\" "+coords.size()+" time(s)!"); Log.log(LogLevel.Info, "["+this.getName()+"] Going to place \""+file.getName()+"\" "+coords.size()+" time(s)!");

Loading…
Cancel
Save