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;
import java.io.File;
import java.util.HashMap;
import peery.file.FileHandler;
import peery.file.SettingsHandler;
import peery.log.Log;
import peery.log.LogLevel;
import peery.picture.ImageAnalyzer;
import peery.picture.ImageUtils;
public class Mosaic extends Thread{
public static final String programmName = "Mosaic",
versionString = "Alpha-0.33";
versionString = "Alpha-0.40";
private static final String outputName = "Output";
private static final int gridX = 100, gridY = 50, targetMulti = 2,
private static String outputName = "Output";
private static int gridWidth = 100, gridHeight = 100, targetMulti = 2,
alphaThreshhold = 30,
adaptionCount = 300,
inputWorkerLimit = 10,
targetWorkerLimit = 4,
targetWorkerLimit = 8,
matchWorkerLimit = 10,
placeWorkerLimit = 2;
private static final double adaptionStep = 1.1, gridErrorThresh = 0.15;
private static boolean keepRatio = false;
placeWorkerLimit = 2; //get overwritten by file settings
private static double adaptionStep = 1.1, gridErrorThresh = 0.15;
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:
* rasterization doesn't cover everything!
@ -36,6 +42,7 @@ public class Mosaic extends Thread{
* explore guarantee of usage of at least once, each image.
*/
public SettingsHandler sh;
public FileHandler fh;
public ImageAnalyzer ia;
@ -43,17 +50,26 @@ public class Mosaic extends Thread{
fh = new FileHandler("resources");
Log.log(LogLevel.Info, "Starting "+programmName+" "+versionString);
ia = new ImageAnalyzer(fh, inputWorkerLimit, targetWorkerLimit, matchWorkerLimit,
placeWorkerLimit, alphaThreshhold, keepRatio);
placeWorkerLimit, alphaThreshhold, keepRatio, overlapImages);
sh = new SettingsHandler(fh, "settings.txt");
this.start();
}
public void run(){
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 ...");
prepMatching();
//Log.log(LogLevel.Error, ia.slotClassifications.toString()+" prep:"+ia.isPrepInProgress());
//Log.log(LogLevel.Error, ia.slotClassifications.toString()+" prep:"+ia.isPrepInProgress());
while(ia.isPrepInProgress()){
try {
@ -82,13 +98,14 @@ public class Mosaic extends Thread{
e.printStackTrace();
}
}
cutOutGrid();
ImageUtils.cutOutGrid(ia);
Log.log.perfLog("Finished Placement!");
Log.log(LogLevel.Info, "Finished placement. Output is done ...");
Log.log.perfLog("Saving output to file ...");
fh.saveImage(ia.canvas, new File(fh.OutputFolder+fh.fs+outputName+"-"+fh.OutputFolder.listFiles().length+".png"));
Log.log.perfLog("Everything done! Exiting ...");
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.
*/
public void prepMatching(){
ia.rasterizeTarget(gridX, gridY, targetMulti, gridErrorThresh, adaptionCount, adaptionStep);
ia.rasterizeTarget(gridWidth, gridHeight, targetMulti, gridErrorThresh, adaptionCount, adaptionStep);
ia.updateIndex();
ia.classifyTarget();
}
@ -112,12 +129,49 @@ public class Mosaic extends Thread{
ia.placeFragments();
}
public void cutOutGrid(){
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]);
public void importSettings(HashMap<String, String> settings){
if(0 < settings.get("version").compareTo(versionString)){
Log.log(LogLevel.Error, "Won't import settings! Version String doesn't match!");
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){
new Mosaic();
}

@ -213,6 +213,23 @@ public class FileHandler {
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
* @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 static Log log;
public static final boolean silenceDebug = false,
public static final boolean silenceDebug = true,
appendEvents = false, appendErrors = false;
private final static String readmeText =
@ -73,6 +73,7 @@ public class Log {
try {
Log.log.errorWriter.close();
Log.log.eventWriter.close();
Log.log.perfWriter.close();
Log.log = null;
} catch (IOException e) {
e.printStackTrace();

@ -29,7 +29,7 @@ public class ImageAnalyzer {
private HashMap<String, Integer> index;
private int alphaThreshhold;
public final boolean keepRatio;
public final boolean keepRatio, overlapImages;
public int[] gridEnd;
//Input Classification Worker
@ -59,11 +59,13 @@ public class ImageAnalyzer {
//
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.target = fh.loadImage(fh.TargetImageFile);
this.alphaThreshhold = alphaThreshhold;
this.keepRatio = keepRatio;
this.overlapImages = overlapImages;
this.gridEnd = new int[2];
this.inputWorkersLimit = inputWorkersLimit;
@ -140,7 +142,7 @@ public class ImageAnalyzer {
}
}
Log.log(LogLevel.Info, "Work list filled with "+inputFiles.size()+" file(s)!");
if(inputFiles.size() <= 0){
Log.log(LogLevel.Info, "No work then! Ending Index Update ...");
return;
@ -335,7 +337,8 @@ public class ImageAnalyzer {
Log.log(LogLevel.Debug, "Target will be "+(int)(targetSize.width*targetSizeMultiplier)
+"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;
slotY = gridY;
slotCount = gridX*gridY;

@ -5,37 +5,63 @@ import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import peery.log.Log;
import peery.log.LogLevel;
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;
BufferedImage img;
int imageWidth, imageHeight;
if(!keepRatio){
tmp = input.getScaledInstance((int)targetSize.getWidth(), (int)targetSize.getHeight(), Image.SCALE_SMOOTH);
img = new BufferedImage(tmp.getWidth(null), tmp.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = (Graphics2D) img.getGraphics();
g2.drawImage(tmp, 0, 0, null);
g2.dispose();
return img;
imageWidth = (int)targetSize.getWidth();
imageHeight = (int)targetSize.getHeight();
}
if(input.getWidth() > input.getHeight()){
tmp = input.getScaledInstance((int)targetSize.getWidth(), -1, Image.SCALE_SMOOTH);
img = new BufferedImage(tmp.getWidth(null), tmp.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = (Graphics2D) img.getGraphics();
g2.drawImage(tmp, 0, 0, null);
g2.dispose();
return img;
}else{
tmp = input.getScaledInstance(-1, (int)targetSize.getHeight(), Image.SCALE_SMOOTH);
img = new BufferedImage(tmp.getWidth(null), tmp.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = (Graphics2D) img.getGraphics();
g2.drawImage(tmp, 0, 0, null);
g2.dispose();
return img;
else{
if(!overlapImages){
if(input.getWidth() > input.getHeight()){
imageWidth = (int)targetSize.getWidth();
imageHeight = -1;
}else{
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);
Graphics2D g2 = (Graphics2D) img.getGraphics();
g2.drawImage(tmp, 0, 0, null);
g2.dispose();
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() {
Log.log(LogLevel.Info, "Worker "+this.getName()+" commencing work!");
for(File file: coordMap.keySet()){
if(coordMap.get(file) == null){
if(coordMap.get(file) == null){ //Check to avoid NullPointerException
continue;
}
BufferedImage img = ia.fh.loadImage(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.Info, "["+this.getName()+"] Going to place \""+file.getName()+"\" "+coords.size()+" time(s)!");

Loading…
Cancel
Save