added possibility to choose image paths via UI; TODO: enforce Model-View-Controller + add image downloader

This commit is contained in:
Hannes
2017-09-18 15:24:52 +02:00
parent 237aae7d5b
commit e12ae4a748
4 changed files with 239 additions and 109 deletions

View File

@@ -1,29 +1,128 @@
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import xkcd.construction.ImageArranger; import xkcd.construction.ImageArranger;
import xkcd.construction.ImageDataLoader; import xkcd.construction.ImageDataLoader;
import xkcd.construction.ImageSticher; import xkcd.construction.ImageSticher;
import xkcd.rectangle.imagepath.PathRectangle; import xkcd.rectangle.imagepath.PathRectangle;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
public class Main { public class Main {
static final String PATH = "C:\\Users\\Hannes\\xkcd\\"; private double aspectRatio;
private Collection<File> inputImages;
private File outputImagePath;
public static void main(final String[] args) throws IOException { public Main() {
System.out.println("Loading Now!"); this.aspectRatio = 3D / 2D;
final ImageDataLoader loader = new ImageDataLoader(); }
Collection<PathRectangle> images = loader.load(new File(PATH));
System.out.println("Arranging Now!"); public Main(final double outputAspectRatio) {
final ImageArranger arranger = new ImageArranger(); this.aspectRatio = outputAspectRatio;
images = arranger.arrangeRectangles(images, 3D / 2D); }
System.out.println("Count: " + images.size());
System.out.println("Saving Now!"); public Main(final Collection<File> input, final File output) {
final ImageSticher sticher = new ImageSticher(images); this.inputImages = input;
sticher.saveImage(new File("C:\\Users\\Hannes\\Desktop\\savedNew.png")); this.outputImagePath = output;
System.out.println("DONE!"); }
}
public Main(final Collection<File> input, final File output, final double outputAspectRatio) {
this.aspectRatio = outputAspectRatio;
this.inputImages = input;
this.outputImagePath = output;
}
public void selectFilesDialog() {
this.inputImages = new LinkedList<>();
JFileChooser fileChooser;
fileChooser = new JFileChooser();
// FileOpenDialog
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
fileChooser.setDialogTitle("Load Images File or Directory");
fileChooser.setMultiSelectionEnabled(true);
int returnVal = fileChooser.showOpenDialog(null);
if (returnVal != JFileChooser.APPROVE_OPTION) {
System.out.println("Aborted!");
return;
}
for (final File file : fileChooser.getSelectedFiles()) {
inputImages.add(file);
}
// FileSaveDialog
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
fileChooser.setDialogTitle("Save Image");
fileChooser.setMultiSelectionEnabled(false);
fileChooser.setFileFilter(new FileFilter() {
@Override
public String getDescription() {
return ".png";
}
@Override
public boolean accept(final File f) {
return true;
}
});
returnVal = fileChooser.showSaveDialog(null);
if (returnVal != JFileChooser.APPROVE_OPTION) {
System.out.println("Aborted!");
return;
}
if (!fileChooser.getSelectedFile().getName().endsWith(".png")) {
fileChooser.setSelectedFile(new File(fileChooser.getSelectedFile().getAbsolutePath() + ".png"));
}
this.outputImagePath = fileChooser.getSelectedFile();
}
public void run() {
if (inputImages == null || inputImages.size() == 0 || outputImagePath == null) {
return;
}
System.out.println("Loading Now!");
final ImageDataLoader loader = new ImageDataLoader();
Collection<PathRectangle> images;
if (inputImages.size() == 1 && ((File) inputImages.toArray()[0]).isDirectory()) {
images = loader.load(((File) inputImages.toArray()[0]));
} else {
images = loader.load(inputImages);
}
System.out.println("Arranging Now!");
final ImageArranger arranger = new ImageArranger();
images = arranger.arrangeRectangles(images, aspectRatio);
System.out.println("Count: " + images.size());
System.out.println("Saving Now!");
final ImageSticher sticher = new ImageSticher(images);
try {
// TODO: take scaling into account
sticher.saveImage(outputImagePath);
} catch (final IOException e) {
// TODO: catch exception in appropriate way
e.printStackTrace();
}
System.out.println("DONE!");
}
public static void main(final String[] args) throws IOException {
final Main main = new Main();
main.selectFilesDialog();
main.run();
}
} }

View File

@@ -14,9 +14,8 @@ import java.util.Comparator;
*/ */
public class ImageMegapixelComparator implements Comparator<BufferedImage> { public class ImageMegapixelComparator implements Comparator<BufferedImage> {
@Override @Override
public int compare(BufferedImage o1, BufferedImage o2) { public int compare(final BufferedImage o1, final BufferedImage o2) {
return o2.getWidth() * o2.getHeight() - o1.getWidth() * o1.getHeight(); return o2.getWidth() * o2.getHeight() - o1.getWidth() * o1.getHeight();
} }
} }

View File

@@ -5,56 +5,83 @@
*/ */
package xkcd.construction; package xkcd.construction;
import xkcd.rectangle.imagepath.PathRectangle;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedList;
import javax.imageio.ImageIO;
import xkcd.rectangle.imagepath.PathRectangle;
/** /**
* @author Hannes * @author Hannes
*/ */
public class ImageDataLoader { public class ImageDataLoader {
public ImageDataLoader() { public ImageDataLoader() {
} }
public Collection<PathRectangle> load(final File path) { /**
final Collection<PathRectangle> rectangles = new ArrayList<>(); * loads images from a directory and all subdirectories
*
* @param directoryPath
* path to the directory
* @return returns a collection of loaded pathrectangles
*/
public Collection<PathRectangle> load(final File directoryPath) {
return load(loadFromDirectory(directoryPath));
}
rectangles.addAll(loadFromDirectory(path)); /**
* Loads images from the specified paths in the collection
*
* @param paths
* collection of paths to the images that should be loaded
* @return returns the loaded pathRectangles
*/
public Collection<PathRectangle> load(final Collection<File> paths) {
final Collection<PathRectangle> images = new LinkedList<>();
for (final File file : paths) {
if (loadFile(file) != null) {
images.add(loadFile(file));
}
}
return images;
}
return rectangles; /**
} * Searches recursively through a directory and adds all files to a list that is
* returned
*
* @param directory
* the directory that will be searched through
* @return returns all the added files from the directory
*/
private Collection<File> loadFromDirectory(final File directory) {
final Collection<File> files = new LinkedList<>();
private Collection<PathRectangle> loadFromDirectory(final File directory) { for (final File fileEntry : directory.listFiles()) {
final Collection<PathRectangle> rectangles = new ArrayList<>(); if (fileEntry.isDirectory()) {
files.addAll(loadFromDirectory(fileEntry));
} else {
files.add(fileEntry);
}
}
return files;
}
for (final File fileEntry : directory.listFiles()) { private PathRectangle loadFile(final File file) {
if (fileEntry.isDirectory()) { try {
rectangles.addAll(loadFromDirectory(fileEntry)); final BufferedImage tmpImage = ImageIO.read(file);
} else { // TODO use correct rotation data of an Image and rotate image if necessary
if (loadFile(fileEntry) != null) { if (tmpImage == null) {
rectangles.add(loadFile(fileEntry)); return null;
} }
} return new PathRectangle(file, 0, 0, tmpImage.getWidth(), tmpImage.getHeight());
}
return rectangles;
}
private PathRectangle loadFile(final File file) { } catch (final IOException ex) {
try { return null;
final BufferedImage tmpImage = ImageIO.read(file); }
//TODO use correct rotation data of an Image and rotate image if necessary }
if (tmpImage == null) {
return null;
}
return new PathRectangle(file, 0, 0, tmpImage.getWidth(), tmpImage.getHeight());
} catch (final IOException ex) {
return null;
}
}
} }

View File

@@ -5,71 +5,76 @@
*/ */
package xkcd.construction; package xkcd.construction;
import xkcd.rectangle.imagepath.PathRectangle; import java.awt.Color;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import javax.imageio.ImageIO;
import xkcd.rectangle.imagepath.PathRectangle;
/** /**
* @author Hannes * @author Hannes
*/ */
public class ImageSticher { public class ImageSticher {
private final double scaleTo = 0.1D; private static final double DEFAULT_SCALE = 0.1D;
private static final int IMAGE_TYPE = BufferedImage.TYPE_4BYTE_ABGR; private static final int IMAGE_TYPE = BufferedImage.TYPE_4BYTE_ABGR;
private static final Color BACKGROUND_COLOR = Color.BLACK; private static final Color BACKGROUND_COLOR = Color.BLACK;
private BufferedImage collage; private BufferedImage collage;
private final Collection<PathRectangle> rectangles; private final Collection<PathRectangle> rectangles;
public ImageSticher(final Collection<PathRectangle> rect) { public ImageSticher(final Collection<PathRectangle> rect) {
this.rectangles = rect; this.rectangles = rect;
//System.out.println("Count: " + rectangles.size()); }
this.initBufferedImage();
}
public void saveImage(final File saveFile) throws IOException { public void saveImage(final File saveFile) throws IOException {
initBufferedImage(); saveImage(saveFile, DEFAULT_SCALE);
for (final PathRectangle rectangle : rectangles) { }
try {
final BufferedImage image = loadImage(rectangle.getPath());
//System.out.println(rectangle);
collage.getGraphics().drawImage(image, (int) (rectangle.getX() * scaleTo), (int) (rectangle.getY() * scaleTo),
(int) (rectangle.getWidth() * scaleTo), (int) (rectangle.getHeight() * scaleTo), null);
} catch (final IOException ex) {
System.err.println(ex.getMessage());
}
}
ImageIO.write(collage, "png", saveFile);
}
private void initBufferedImage() { public void saveImage(final File saveFile, final double scale) throws IOException {
int width = 0; initBufferedImage(scale);
int height = 0; for (final PathRectangle rectangle : rectangles) {
for (final PathRectangle rectangle : rectangles) { try {
final int tmpWidth = (int) (rectangle.getWidth() + rectangle.getX()); final BufferedImage image = loadImage(rectangle.getPath());
final int tmpHeight = (int) (rectangle.getHeight() + rectangle.getY()); // System.out.println(rectangle);
collage.getGraphics().drawImage(image, (int) (rectangle.getX() * scale),
(int) (rectangle.getY() * scale), (int) (rectangle.getWidth() * scale),
(int) (rectangle.getHeight() * scale), null);
} catch (final IOException ex) {
System.err.println(ex.getMessage());
}
}
ImageIO.write(collage, "png", saveFile);
}
private void initBufferedImage(final double scale) {
int width = 0;
int height = 0;
for (final PathRectangle rectangle : rectangles) {
final int tmpWidth = (int) (rectangle.getWidth() + rectangle.getX());
final int tmpHeight = (int) (rectangle.getHeight() + rectangle.getY());
if (tmpWidth > width) { if (tmpWidth > width) {
width = tmpWidth; width = tmpWidth;
} }
if (tmpHeight > height) { if (tmpHeight > height) {
height = tmpHeight; height = tmpHeight;
} }
} }
collage = new BufferedImage((int) (width * scaleTo), (int) (height * scaleTo), IMAGE_TYPE); collage = new BufferedImage((int) (width * scale), (int) (height * scale), IMAGE_TYPE);
//collage.getGraphics().setColor(BACKGROUND_COLOR); // collage.getGraphics().setColor(BACKGROUND_COLOR);
//collage.getGraphics().drawRect(0, 0, collage.getWidth(), collage.getHeight()); // collage.getGraphics().drawRect(0, 0, collage.getWidth(),
//collage.getGraphics().fillRect(0, 0, collage.getWidth(), collage.getHeight()); // collage.getHeight());
} // collage.getGraphics().fillRect(0, 0, collage.getWidth(),
// collage.getHeight());
}
private BufferedImage loadImage(final File filePath) throws IOException { private BufferedImage loadImage(final File filePath) throws IOException {
return ImageIO.read(filePath); return ImageIO.read(filePath);
} }
} }