mirror of
https://github.com/13hannes11/xkcd_poster_creator.git
synced 2024-09-03 21:50:58 +02:00
added the xkcd downloader project to the repo and reorderd repo directories
This commit is contained in:
11
xkcd_downloader/.settings/org.eclipse.jdt.core.prefs
Normal file
11
xkcd_downloader/.settings/org.eclipse.jdt.core.prefs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.8
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package org.kuchelmeister.xkcd.downloader;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ImageDownloader {
|
||||||
|
|
||||||
|
List<String> downloadedImages;
|
||||||
|
|
||||||
|
public ImageDownloader() {
|
||||||
|
downloadedImages = new LinkedList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadImage(final String url, final String folderPath) throws IOException {
|
||||||
|
final InputStream in = new URL(url).openStream();
|
||||||
|
final String fileName = url.substring(url.lastIndexOf("/")).replaceAll("[^A-Za-z0-9.]", "");
|
||||||
|
|
||||||
|
downloadedImages.add(folderPath + fileName);
|
||||||
|
|
||||||
|
Files.copy(in, Paths.get(folderPath + fileName));
|
||||||
|
|
||||||
|
System.out.println("Saved: " + folderPath + fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void downloadAllImages(final List<String> images, final String folderPath) {
|
||||||
|
for (final String img : images) {
|
||||||
|
try {
|
||||||
|
this.downloadImage(img, folderPath);
|
||||||
|
} catch (final IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package org.kuchelmeister.xkcd.downloader;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
public class ImageFinder {
|
||||||
|
public static final String NUM_REPLACE = "<number>";
|
||||||
|
public static final String XKCD_URL = "https://xkcd.com/" + NUM_REPLACE + "/info.0.json";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of tries until fetching is aborted
|
||||||
|
*/
|
||||||
|
public static final int ABORT_THRESHOLD = 10;
|
||||||
|
|
||||||
|
private final List<String> imageURLs;
|
||||||
|
|
||||||
|
public ImageFinder() {
|
||||||
|
this.imageURLs = new LinkedList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void findImages() {
|
||||||
|
int err_counter = 0;
|
||||||
|
int counter = 1;
|
||||||
|
while (err_counter < ABORT_THRESHOLD) {
|
||||||
|
final String url = XKCD_URL.replace(NUM_REPLACE, Integer.toString(counter++));
|
||||||
|
|
||||||
|
try {
|
||||||
|
final JSONObject jsonObj = readJsonFromUrl(url);
|
||||||
|
|
||||||
|
this.getImageURLs().add(jsonObj.get("img").toString());
|
||||||
|
System.out.println(jsonObj.get("img").toString());
|
||||||
|
|
||||||
|
err_counter = 0;
|
||||||
|
} catch (JSONException | IOException e) {
|
||||||
|
err_counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONObject readJsonFromUrl(final String url) throws IOException, JSONException {
|
||||||
|
final InputStream is = new URL(url).openStream();
|
||||||
|
try {
|
||||||
|
final BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
|
||||||
|
final String jsonText = readAll(rd);
|
||||||
|
final JSONObject json = new JSONObject(jsonText);
|
||||||
|
return json;
|
||||||
|
} finally {
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String readAll(final Reader rd) throws IOException {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
int cp;
|
||||||
|
while ((cp = rd.read()) != -1) {
|
||||||
|
sb.append((char) cp);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the imageURLs
|
||||||
|
*/
|
||||||
|
public List<String> getImageURLs() {
|
||||||
|
return imageURLs;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package org.kuchelmeister.xkcd.downloader;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static void main(final String[] args) {
|
||||||
|
final ImageFinder finder = new ImageFinder();
|
||||||
|
final ImageDownloader downloader = new ImageDownloader();
|
||||||
|
|
||||||
|
finder.findImages();
|
||||||
|
downloader.downloadAllImages(finder.getImageURLs(), "C:/Users/Hannes/Pictures/xkcd/");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package org.kuchelmeister.xkcd.downloader;
|
||||||
|
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Suite;
|
||||||
|
import org.junit.runners.Suite.SuiteClasses;
|
||||||
|
|
||||||
|
@RunWith(Suite.class)
|
||||||
|
@SuiteClasses({ ImageDonwloaderTest.class })
|
||||||
|
public class AllTests {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package org.kuchelmeister.xkcd.downloader;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ImageDonwloaderTest {
|
||||||
|
@Test
|
||||||
|
public void noFolderExistsDownloadTest() {
|
||||||
|
final String url = "https://imgs.xkcd.com/comics/barrel_cropped_(1).jpg";
|
||||||
|
final String folderDIR = "testing";
|
||||||
|
final ImageDownloader downloader = new ImageDownloader();
|
||||||
|
|
||||||
|
final List<String> urls = new LinkedList<>();
|
||||||
|
|
||||||
|
urls.add(url);
|
||||||
|
|
||||||
|
final File f = new File(folderDIR);
|
||||||
|
if (f.exists()) {
|
||||||
|
f.delete();
|
||||||
|
}
|
||||||
|
downloader.downloadAllImages(urls, folderDIR);
|
||||||
|
|
||||||
|
org.junit.Assert.assertEquals(true, f.exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
12
xkcd_poster/XKCDPoster.iml
Normal file
12
xkcd_poster/XKCDPoster.iml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
|
|
||||||
2
xkcd_poster/bin/.gitignore
vendored
Normal file
2
xkcd_poster/bin/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/org/
|
||||||
|
/xkcd/
|
||||||
130
xkcd_poster/src/org/kuchelmeister/xkcd/poster/Main.java
Normal file
130
xkcd_poster/src/org/kuchelmeister/xkcd/poster/Main.java
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
package org.kuchelmeister.xkcd.poster;
|
||||||
|
|
||||||
|
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 org.kuchelmeister.xkcd.poster.construction.ImageArranger;
|
||||||
|
import org.kuchelmeister.xkcd.poster.construction.ImageDataLoader;
|
||||||
|
import org.kuchelmeister.xkcd.poster.construction.ImageSticher;
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.imagepath.PathRectangle;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
private double aspectRatio;
|
||||||
|
private Collection<File> inputImages;
|
||||||
|
private File outputImagePath;
|
||||||
|
|
||||||
|
public Main() {
|
||||||
|
this.aspectRatio = 3D / 2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Main(final double outputAspectRatio) {
|
||||||
|
this.aspectRatio = outputAspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Main(final Collection<File> input, final File output) {
|
||||||
|
this.inputImages = input;
|
||||||
|
this.outputImagePath = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.kuchelmeister.xkcd.poster;
|
||||||
|
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class RectangleImage {
|
||||||
|
Rectangle r;
|
||||||
|
|
||||||
|
public RectangleImage(BufferedImage image, int x, int y) {
|
||||||
|
r = new Rectangle(x, y, image.getWidth(), image.getHeight());
|
||||||
|
}
|
||||||
|
public RectangleImage(Rectangle rec){
|
||||||
|
r = rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return r.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return r.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBoundY() {
|
||||||
|
return r.y + r.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBoundX() {
|
||||||
|
return r.x + r.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return r.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return r.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rectangle getRectangle() {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
public void setY(int y){
|
||||||
|
r.y = y;
|
||||||
|
}
|
||||||
|
public boolean intersects(RectangleImage image) {
|
||||||
|
return r.intersects(image.getRectangle());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.kuchelmeister.xkcd.poster.construction;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.construction.comparator.AreaComparator;
|
||||||
|
import org.kuchelmeister.xkcd.poster.construction.comparator.HeightFirstComparator;
|
||||||
|
import org.kuchelmeister.xkcd.poster.construction.comparator.WidthFirstComparator;
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.freespace.ClockwiseSplitFreeSpaceRectangle;
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.freespace.FreeSpaceRectangle;
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.imagepath.PathRectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class ImageArranger {
|
||||||
|
|
||||||
|
private final FreeSpaceRectangle currentBounds;
|
||||||
|
|
||||||
|
private final Collection<PathRectangle> placed;
|
||||||
|
|
||||||
|
private final double factor;
|
||||||
|
private final int startStepCount;
|
||||||
|
private final int stopper;
|
||||||
|
|
||||||
|
public ImageArranger() {
|
||||||
|
factor = 0.5D;
|
||||||
|
startStepCount = 10000;
|
||||||
|
stopper = 500;
|
||||||
|
|
||||||
|
currentBounds = null;
|
||||||
|
|
||||||
|
placed = new ArrayList<>();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shifts the left top corener to the coordinates (0;0)
|
||||||
|
*/
|
||||||
|
private void shiftToLeftTop() {
|
||||||
|
if (currentBounds == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final int x = (int) -currentBounds.getX();
|
||||||
|
final int y = (int) -currentBounds.getY();
|
||||||
|
|
||||||
|
for (final PathRectangle rect : placed) {
|
||||||
|
rect.setX((int) (rect.getX() + x));
|
||||||
|
rect.setY((int) (rect.getY() + y));
|
||||||
|
}
|
||||||
|
currentBounds.setX(0);
|
||||||
|
currentBounds.setY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<PathRectangle> arrangeRectangles(final Collection<PathRectangle> rectangles,
|
||||||
|
final double heightToWidthRatio) {
|
||||||
|
int stepCount = startStepCount;
|
||||||
|
|
||||||
|
int height = stepCount;
|
||||||
|
int width = calcWidthFromHeight(stepCount, heightToWidthRatio);
|
||||||
|
|
||||||
|
int direction = 1;
|
||||||
|
boolean readyToStop = false;
|
||||||
|
|
||||||
|
while (!readyToStop || arrangeRectangles(rectangles, width, height) == null) {
|
||||||
|
// Loopcancelpermission: if accuracy is reached (stopper) and direction is from
|
||||||
|
// to small to to big (direction > 0)
|
||||||
|
if (stepCount < stopper && direction > 0) {
|
||||||
|
readyToStop = true;
|
||||||
|
}
|
||||||
|
if ((arrangeRectangles(rectangles, width, height) != null && direction > 0)
|
||||||
|
|| (arrangeRectangles(rectangles, width, height) == null && direction < 0)) {
|
||||||
|
stepCount *= factor;
|
||||||
|
direction *= -1;
|
||||||
|
}
|
||||||
|
height += direction * stepCount;
|
||||||
|
width = calcWidthFromHeight(height, heightToWidthRatio);
|
||||||
|
System.out.println("W: " + width + " H:" + height + " StepCount: " + stepCount + " Direction: " + direction
|
||||||
|
+ " ArrangeRectangles: " + ((arrangeRectangles(rectangles, width, height) == null) ? null
|
||||||
|
: arrangeRectangles(rectangles, width, height).size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return arrangeRectangles(rectangles, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calcWidthFromHeight(final int height, final double heightToWidthRatio) {
|
||||||
|
return (int) Math.round(height * heightToWidthRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<PathRectangle> arrangeRectangles(final Collection<PathRectangle> rectangles, final int width,
|
||||||
|
final int height) {
|
||||||
|
// System.out.println("Size: " + rectangles);
|
||||||
|
|
||||||
|
placed.clear();
|
||||||
|
final TreeSet<PathRectangle> widthSortedSet = new TreeSet<>(new WidthFirstComparator());
|
||||||
|
final TreeSet<PathRectangle> heightSortedSet = new TreeSet<>(new HeightFirstComparator());
|
||||||
|
|
||||||
|
final TreeSet<FreeSpaceRectangle> freeSpaceArea = new TreeSet<>(new AreaComparator());
|
||||||
|
|
||||||
|
widthSortedSet.addAll(rectangles);
|
||||||
|
heightSortedSet.addAll(rectangles);
|
||||||
|
|
||||||
|
freeSpaceArea.add(new ClockwiseSplitFreeSpaceRectangle(0, 0, width, height));
|
||||||
|
|
||||||
|
while (widthSortedSet.size() > 0 && heightSortedSet.size() > 0) {
|
||||||
|
final PathRectangle _tmp = (widthSortedSet.last().getWidth() > heightSortedSet.last().getHeight())
|
||||||
|
? widthSortedSet.last()
|
||||||
|
: heightSortedSet.last();
|
||||||
|
|
||||||
|
widthSortedSet.remove(_tmp);
|
||||||
|
heightSortedSet.remove(_tmp);
|
||||||
|
|
||||||
|
FreeSpaceRectangle _space = null;
|
||||||
|
|
||||||
|
for (final FreeSpaceRectangle s : freeSpaceArea) {
|
||||||
|
if (s.couldContain(_tmp)) {
|
||||||
|
_space = s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// No space means not every image can be placed
|
||||||
|
if (_space == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
placed.add(_tmp);
|
||||||
|
_tmp.setLocation((int) _space.getX(), (int) _space.getY());
|
||||||
|
freeSpaceArea.addAll(_space.divideUp(_tmp));
|
||||||
|
freeSpaceArea.remove(_space);
|
||||||
|
}
|
||||||
|
|
||||||
|
shiftToLeftTop();
|
||||||
|
|
||||||
|
// <DEBUG>
|
||||||
|
/*
|
||||||
|
* double spaceHeight = 0; double spaceWidth = 0; for (final FreeSpaceRectangle
|
||||||
|
* rect : freeSpaceArea) { if (rect.getWidth() + rect.getX() > spaceWidth) {
|
||||||
|
* spaceWidth = rect.getWidth() + rect.getX(); } if (rect.getHeight() +
|
||||||
|
* rect.getY() > spaceHeight) { spaceHeight = rect.getHeight() + rect.getY(); }
|
||||||
|
* } final double multiplier = 0.1; final BufferedImage bImage = new
|
||||||
|
* BufferedImage((int) (spaceWidth * multiplier), (int) (spaceHeight *
|
||||||
|
* multiplier), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
*
|
||||||
|
* for (final FreeSpaceRectangle rect : freeSpaceArea) { final Graphics g =
|
||||||
|
* bImage.getGraphics();
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* g.setColor(Color.blue); g.fillRect((int) (rect.getX() * multiplier), (int)
|
||||||
|
* (rect.getY() * multiplier), (int) (rect.getWidth() * multiplier), (int)
|
||||||
|
* (rect.getHeight() * multiplier)); g.setColor(Color.red); g.drawRect((int)
|
||||||
|
* (rect.getX() * multiplier), (int) (rect.getY() * multiplier), (int)
|
||||||
|
* (rect.getWidth() * multiplier), (int) (rect.getHeight() * multiplier)); } try
|
||||||
|
* { ImageIO.write(bImage, "png", new
|
||||||
|
* File("C:\\Users\\Hannes\\Desktop\\savedNewFreeSpace.png")); } catch (final
|
||||||
|
* IOException e) { e.printStackTrace(); }
|
||||||
|
*/
|
||||||
|
// </DEGUB>
|
||||||
|
return placed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PathRectangle getNextPathRectangle(final PathRectangle widthRec, final PathRectangle heightRect) {
|
||||||
|
return (widthRec.getWidth() > heightRect.getHeight()) ? widthRec : heightRect;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.kuchelmeister.xkcd.poster.construction;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.imagepath.PathRectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class ImageDataLoader {
|
||||||
|
public ImageDataLoader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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<>();
|
||||||
|
|
||||||
|
for (final File fileEntry : directory.listFiles()) {
|
||||||
|
if (fileEntry.isDirectory()) {
|
||||||
|
files.addAll(loadFromDirectory(fileEntry));
|
||||||
|
} else {
|
||||||
|
files.add(fileEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PathRectangle loadFile(final File file) {
|
||||||
|
try {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.kuchelmeister.xkcd.poster.construction;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.imagepath.PathRectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class ImageSticher {
|
||||||
|
private static final double DEFAULT_SCALE = 1D;
|
||||||
|
private static final int IMAGE_TYPE = BufferedImage.TYPE_4BYTE_ABGR;
|
||||||
|
private static final Color BACKGROUND_COLOR = Color.BLACK;
|
||||||
|
|
||||||
|
private BufferedImage collage;
|
||||||
|
private final Collection<PathRectangle> rectangles;
|
||||||
|
|
||||||
|
public ImageSticher(final Collection<PathRectangle> rect) {
|
||||||
|
this.rectangles = rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveImage(final File saveFile) throws IOException {
|
||||||
|
saveImage(saveFile, DEFAULT_SCALE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveImage(final File saveFile, final double scale) throws IOException {
|
||||||
|
initBufferedImage(scale);
|
||||||
|
for (final PathRectangle rectangle : rectangles) {
|
||||||
|
try {
|
||||||
|
final BufferedImage image = loadImage(rectangle.getPath());
|
||||||
|
// 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) {
|
||||||
|
width = tmpWidth;
|
||||||
|
}
|
||||||
|
if (tmpHeight > height) {
|
||||||
|
height = tmpHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collage = new BufferedImage((int) (width * scale), (int) (height * scale), IMAGE_TYPE);
|
||||||
|
|
||||||
|
// collage.getGraphics().setColor(BACKGROUND_COLOR);
|
||||||
|
// collage.getGraphics().drawRect(0, 0, collage.getWidth(),
|
||||||
|
// collage.getHeight());
|
||||||
|
// collage.getGraphics().fillRect(0, 0, collage.getWidth(),
|
||||||
|
// collage.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
private BufferedImage loadImage(final File filePath) throws IOException {
|
||||||
|
return ImageIO.read(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.kuchelmeister.xkcd.poster.construction.comparator;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class AreaComparator implements Comparator<CustomRectangle> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(final CustomRectangle o1, final CustomRectangle o2) {
|
||||||
|
if (Double.compare(o1.width * o1.height, o2.width * o2.height) == 0) {
|
||||||
|
return Integer.compare(o1.hashCode(), o2.hashCode());
|
||||||
|
} else {
|
||||||
|
return Double.compare(o1.width * o1.height, o2.width * o2.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.kuchelmeister.xkcd.poster.construction.comparator;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class HeightFirstComparator implements Comparator<CustomRectangle> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(final CustomRectangle o1, final CustomRectangle o2) {
|
||||||
|
if (Double.compare(o1.getHeight(), o2.getHeight()) == 0) {
|
||||||
|
if (Double.compare(o1.getWidth(), o2.getWidth()) == 0) {
|
||||||
|
return Integer.compare(o1.hashCode(), o2.hashCode());
|
||||||
|
} else {
|
||||||
|
return Double.compare(o1.getWidth(), o2.getWidth());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Double.compare(o1.getHeight(), o2.getHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.kuchelmeister.xkcd.poster.construction.comparator;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class ImageMegapixelComparator implements Comparator<BufferedImage> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(final BufferedImage o1, final BufferedImage o2) {
|
||||||
|
return o2.getWidth() * o2.getHeight() - o1.getWidth() * o1.getHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.kuchelmeister.xkcd.poster.construction.comparator;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class WidthFirstComparator implements Comparator<CustomRectangle> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(final CustomRectangle o1, final CustomRectangle o2) {
|
||||||
|
if (Double.compare(o1.getWidth(), o2.getWidth()) == 0) {
|
||||||
|
if (Double.compare(o1.getHeight(), o2.getHeight()) == 0) {
|
||||||
|
return Integer.compare(o1.hashCode(), o2.hashCode());
|
||||||
|
} else {
|
||||||
|
return Double.compare(o1.getHeight(), o2.getHeight());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Double.compare(o1.getWidth(), o2.getWidth());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.kuchelmeister.xkcd.poster.rectangle;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public abstract class CustomRectangle extends Rectangle {
|
||||||
|
|
||||||
|
public CustomRectangle(final int x, final int y, final int width, final int height) {
|
||||||
|
super(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final void setX(final int x) {
|
||||||
|
this.setLocation(x, (int) this.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setY(final int y) {
|
||||||
|
this.setLocation((int) this.getX(), y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setWidth(final int width) {
|
||||||
|
this.setSize(width, (int) this.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setHeight(final int height) {
|
||||||
|
this.setSize((int) this.getWidth(), height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean couldContain(final Rectangle rect) {
|
||||||
|
return (rect.getWidth() <= this.getWidth() && rect.getHeight() <= this.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String str = "";
|
||||||
|
str += "X: " + this.getX() + " Y: " + this.getY() + " w: " + this.getWidth() + " h: " + this.getHeight();
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package org.kuchelmeister.xkcd.poster.rectangle.freespace;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class ClockwiseSplitFreeSpaceRectangle extends FreeSpaceRectangle {
|
||||||
|
|
||||||
|
public ClockwiseSplitFreeSpaceRectangle(final int x, final int y, final int width, final int height) {
|
||||||
|
super(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
|
||||||
|
// System.out.println("Main: " + r.toString());
|
||||||
|
// System.out.println("THIS: " + this.toString());
|
||||||
|
final Collection<FreeSpaceRectangle> rectangles = new ArrayList<>();
|
||||||
|
if (!this.contains(r)) {
|
||||||
|
return rectangles;
|
||||||
|
}
|
||||||
|
final FreeSpaceFactory factory = new FreeSpaceFactory();
|
||||||
|
|
||||||
|
// Left
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
int tmpWidth = (int) (r.getX() - this.getX());
|
||||||
|
int tmpHeight = (int) (r.getY() + r.getHeight() - this.getY());
|
||||||
|
|
||||||
|
if (tmpHeight > 0 && tmpWidth > 0) {
|
||||||
|
rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight));
|
||||||
|
// System.out.println("Left: " + factory.getFreeSpaceRect(x, y, tmpWidth,
|
||||||
|
// tmpHeight).toString());
|
||||||
|
}
|
||||||
|
// Top
|
||||||
|
x = (int) r.getX();
|
||||||
|
y = (int) this.getY();
|
||||||
|
tmpWidth = (int) (this.getX() + this.getWidth() - r.getX());
|
||||||
|
tmpHeight = (int) (r.getY() - this.getY());
|
||||||
|
|
||||||
|
if (tmpHeight > 0 && tmpWidth > 0) {
|
||||||
|
rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight));
|
||||||
|
// System.out.println("Top: " + factory.getFreeSpaceRect(x, y, tmpWidth,
|
||||||
|
// tmpHeight).toString());
|
||||||
|
}
|
||||||
|
// Right
|
||||||
|
x = (int) (r.getX() + r.getWidth());
|
||||||
|
y = (int) r.getY();
|
||||||
|
tmpWidth = (int) (this.getX() + this.getWidth() - (r.getX() + r.getWidth()));
|
||||||
|
tmpHeight = (int) (this.getY() + this.getHeight() - r.getY());
|
||||||
|
|
||||||
|
if (tmpHeight > 0 && tmpWidth > 0) {
|
||||||
|
rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight));
|
||||||
|
// System.out.println("Right: " + factory.getFreeSpaceRect(x, y, tmpWidth,
|
||||||
|
// tmpHeight).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bottom
|
||||||
|
x = (int) this.getX();
|
||||||
|
y = (int) (r.getY() + r.getHeight());
|
||||||
|
tmpWidth = (int) ((r.getX() + r.getWidth()) - this.getX());
|
||||||
|
tmpHeight = (int) (this.getY() + this.getHeight() - (r.getY() + r.getHeight()));
|
||||||
|
|
||||||
|
if (tmpHeight > 0 && tmpWidth > 0) {
|
||||||
|
rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight));
|
||||||
|
// System.out.println("Bottom: " + factory.getFreeSpaceRect(x, y, tmpWidth,
|
||||||
|
// tmpHeight).toString());
|
||||||
|
}
|
||||||
|
return rectangles;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package org.kuchelmeister.xkcd.poster.rectangle.freespace;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle;
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.freespace.FreeSpaceFactory;
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.freespace.FreeSpaceRectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class CounterclockwiseFreeSpaceRectangle extends FreeSpaceRectangle {
|
||||||
|
|
||||||
|
public CounterclockwiseFreeSpaceRectangle(final int x, final int y, final int width, final int height) {
|
||||||
|
super(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
|
||||||
|
// System.out.println("Main: " + r.toString());
|
||||||
|
// System.out.println("THIS: " + this.toString());
|
||||||
|
final Collection<FreeSpaceRectangle> rectangles = new ArrayList<>();
|
||||||
|
if (!this.contains(r)) {
|
||||||
|
return rectangles;
|
||||||
|
}
|
||||||
|
final FreeSpaceFactory factory = new FreeSpaceFactory();
|
||||||
|
|
||||||
|
// Left
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
int tmpWidth = (int) ((r.getX() + r.getWidth()) - this.getX());
|
||||||
|
int tmpHeight = (int) (r.getY() - this.getY());
|
||||||
|
|
||||||
|
if (tmpHeight > 0 && tmpWidth > 0) {
|
||||||
|
rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight));
|
||||||
|
// System.out.println("Left: " + factory.getFreeSpaceRect(x, y, tmpWidth,
|
||||||
|
// tmpHeight).toString());
|
||||||
|
}
|
||||||
|
// Top
|
||||||
|
x = (int) (r.getX() + r.getWidth());
|
||||||
|
y = (int) this.getY();
|
||||||
|
tmpWidth = (int) (this.getX() + this.getWidth() - (r.getX() + r.getWidth()));
|
||||||
|
tmpHeight = (int) (r.getY() + r.getHeight() - this.getY());
|
||||||
|
|
||||||
|
if (tmpHeight > 0 && tmpWidth > 0) {
|
||||||
|
rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight));
|
||||||
|
// System.out.println("Top: " + factory.getFreeSpaceRect(x, y, tmpWidth,
|
||||||
|
// tmpHeight).toString());
|
||||||
|
}
|
||||||
|
// Right
|
||||||
|
x = (int) (r.getX());
|
||||||
|
y = (int) (r.getY() + r.getHeight());
|
||||||
|
tmpWidth = (int) (this.getX() + this.getWidth() - r.getX());
|
||||||
|
tmpHeight = (int) (this.getY() + this.getHeight() - (r.getY() + r.getHeight()));
|
||||||
|
|
||||||
|
if (tmpHeight > 0 && tmpWidth > 0) {
|
||||||
|
rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight));
|
||||||
|
// System.out.println("Right: " + factory.getFreeSpaceRect(x, y, tmpWidth,
|
||||||
|
// tmpHeight).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bottom
|
||||||
|
x = (int) this.getX();
|
||||||
|
y = (int) (r.getY());
|
||||||
|
tmpWidth = (int) (r.getX() - this.getX());
|
||||||
|
tmpHeight = (int) (this.getY() + this.getHeight() - r.getY());
|
||||||
|
|
||||||
|
if (tmpHeight > 0 && tmpWidth > 0) {
|
||||||
|
rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight));
|
||||||
|
// System.out.println("Bottom: " + factory.getFreeSpaceRect(x, y, tmpWidth,
|
||||||
|
// tmpHeight).toString());
|
||||||
|
}
|
||||||
|
return rectangles;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.kuchelmeister.xkcd.poster.rectangle.freespace;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.freespace.ClockwiseSplitFreeSpaceRectangle;
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.freespace.FreeSpaceRectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class FreeSpaceFactory {
|
||||||
|
private int counter;
|
||||||
|
|
||||||
|
public FreeSpaceFactory() {
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FreeSpaceRectangle getFreeSpaceRect(final int x, final int y, final int width, final int height) {
|
||||||
|
counter++;
|
||||||
|
switch (counter % 2) {
|
||||||
|
case 1:
|
||||||
|
return new ClockwiseSplitFreeSpaceRectangle(x, y, width, height);
|
||||||
|
// case 0
|
||||||
|
default:
|
||||||
|
return new CounterclockwiseFreeSpaceRectangle(x, y, width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.kuchelmeister.xkcd.poster.rectangle.freespace;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public abstract class FreeSpaceRectangle extends CustomRectangle {
|
||||||
|
|
||||||
|
public FreeSpaceRectangle(final int x, final int y, final int width, final int height) {
|
||||||
|
super(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method returns the smaller rectangles that will be generated if 'r' is placed
|
||||||
|
* inside the xkcd.rectangle If r is outsdie of this xkcd.rectangle the
|
||||||
|
* Collection will conly contain this. Otherwise it will only contain
|
||||||
|
* subrectangles.
|
||||||
|
*
|
||||||
|
* @param r
|
||||||
|
* the xkcd.rectangle which is placed and arround which shall be
|
||||||
|
* split
|
||||||
|
* @return xkcd.rectangle
|
||||||
|
*/
|
||||||
|
public abstract Collection<FreeSpaceRectangle> divideUp(CustomRectangle r);
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package org.kuchelmeister.xkcd.poster.rectangle.freespace;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle;
|
||||||
|
|
||||||
|
public class LeftRightSplitFreeSpaceRectangle extends FreeSpaceRectangle {
|
||||||
|
|
||||||
|
public LeftRightSplitFreeSpaceRectangle(final int x, final int y, final int width, final int height) {
|
||||||
|
super(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose
|
||||||
|
// Tools | Templates.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.kuchelmeister.xkcd.poster.rectangle.freespace;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class OptimalSplitFreeSpaceRectangle extends FreeSpaceRectangle {
|
||||||
|
|
||||||
|
public OptimalSplitFreeSpaceRectangle(final int x, final int y, final int width, final int height) {
|
||||||
|
super(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose
|
||||||
|
// Tools | Templates.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.kuchelmeister.xkcd.poster.rectangle.freespace;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param <T>
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class TopBottomSplitFreeSpaceRectangle extends FreeSpaceRectangle {
|
||||||
|
|
||||||
|
public TopBottomSplitFreeSpaceRectangle(final int x, final int y, final int width, final int height) {
|
||||||
|
super(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose
|
||||||
|
// Tools | Templates.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.kuchelmeister.xkcd.poster.rectangle.imagepath;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
|
import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes
|
||||||
|
*/
|
||||||
|
public class PathRectangle extends CustomRectangle {
|
||||||
|
private final File path;
|
||||||
|
|
||||||
|
public PathRectangle(final File filePath, final int x, final int y, final int width, final int height)
|
||||||
|
throws FileNotFoundException {
|
||||||
|
super(x, y, width, height);
|
||||||
|
path = filePath;
|
||||||
|
if (!path.exists()) {
|
||||||
|
throw new FileNotFoundException("The filepath is not valid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the path
|
||||||
|
*/
|
||||||
|
public File getPath() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + " Path: " + path.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user