Alpha-0.1 Commit
Tested working on Linux system in development environment. Input pictures are stretched to fit their slots. Configuration lies within the source files.dev
parent
26c183c1e5
commit
9152b37c9f
@ -0,0 +1,122 @@
|
|||||||
|
package peery;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import peery.file.FileHandler;
|
||||||
|
import peery.log.Log;
|
||||||
|
import peery.log.LogLevel;
|
||||||
|
import peery.picture.ImageAnalyzer;
|
||||||
|
|
||||||
|
public class Mosaic {
|
||||||
|
|
||||||
|
public static final String versionString = "Alpha-0.1";
|
||||||
|
|
||||||
|
private static final String outputName = "Output";
|
||||||
|
private static final int gridX = 100, gridY = 100, targetMulti = 4,
|
||||||
|
alphaThreshhold = 30,
|
||||||
|
adaptionCount = 300;
|
||||||
|
private static final double adaptionStep = 1.1, gridErrorThresh = 0.15;
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* TODO improve performance during closest match search. -> Loads ALOT of images
|
||||||
|
* TODO investigate picture stretching -> is ImageUtils.resizeImage() even used?
|
||||||
|
* TODO investigate why so few slots are actually present, I specified way more! <---
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* TODO alphaThreshhold is currently dead
|
||||||
|
*/
|
||||||
|
|
||||||
|
public FileHandler fh;
|
||||||
|
public ImageAnalyzer ia;
|
||||||
|
|
||||||
|
public Mosaic(){
|
||||||
|
fh = new FileHandler("resources");
|
||||||
|
Log.log(LogLevel.Info, "Starting Mosaic "+versionString);
|
||||||
|
ia = new ImageAnalyzer(fh);
|
||||||
|
createMosaic();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createMosaic(){
|
||||||
|
ia.rasterizeTarget(gridX, gridY, targetMulti, gridErrorThresh, adaptionCount, adaptionStep);
|
||||||
|
HashMap<String, Integer> index = fh.loadIndex();
|
||||||
|
|
||||||
|
//Loading index
|
||||||
|
if(index == null){
|
||||||
|
Log.log(LogLevel.Info, "No index loaded. Working with empty one ...");
|
||||||
|
index = new HashMap<String, Integer>();
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//Preparing Setup
|
||||||
|
ArrayList<String> fileList = fh.listInputFiles();
|
||||||
|
|
||||||
|
Log.log(LogLevel.Info, "Starting classification of Input now ...");
|
||||||
|
int count = 0;
|
||||||
|
for(String path: fileList){
|
||||||
|
Log.log(LogLevel.Info, "Processing file "+(count++)+"/"+fileList.size()+" ...");
|
||||||
|
File file = new File(path);
|
||||||
|
BufferedImage img = fh.loadImage(file);
|
||||||
|
if(img == null){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int rgb = ia.classifyImage(img, file, alphaThreshhold);
|
||||||
|
fh.appendToIndex(index, file, rgb);
|
||||||
|
}
|
||||||
|
Log.log(LogLevel.Info, "Finished classification. Index is ready for production. Reloading index ...");
|
||||||
|
index = fh.loadIndex();
|
||||||
|
|
||||||
|
Log.log(LogLevel.Debug, "Canvas is "+ia.canvas.getWidth()+"x"+ia.canvas.getHeight()+" big.");
|
||||||
|
Log.log(LogLevel.Debug, "Grid will span "+ia.slotWidth*gridX+"x"+ia.slotHeight*gridY+" .");
|
||||||
|
Log.log(LogLevel.Info, "Starting classification of target slots.");
|
||||||
|
count = 0;
|
||||||
|
int maxSlot = ia.slotX*ia.slotY;
|
||||||
|
int[][] slotRGBs = new int[ia.slotX][ia.slotY];
|
||||||
|
for(int x = 0; x < ia.slotX; x++){
|
||||||
|
for(int y = 0; y < ia.slotY; y++){
|
||||||
|
Log.log(LogLevel.Info, "Processing slot "+(count++)+"/"+maxSlot+" ...");
|
||||||
|
slotRGBs[x][y] = ia.classifySlot(x, y, ia.target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.log(LogLevel.Info, "Finished classification of target slots.");
|
||||||
|
|
||||||
|
Log.log(LogLevel.Info, "Matching indexed Images on slots ...");
|
||||||
|
count = 0;
|
||||||
|
ArrayList<File> fileHolder = new ArrayList<File>();
|
||||||
|
ArrayList<BufferedImage> imgHolder = new ArrayList<BufferedImage>();
|
||||||
|
for(int x = 0; x < slotRGBs.length; x++){
|
||||||
|
for(int y = 0; y < slotRGBs[x].length; y++){
|
||||||
|
Log.log(LogLevel.Info, "Matching slot "+(count++)+"/"+maxSlot+" ...");
|
||||||
|
HashMap<String, Integer> matches = ia.matchClosestIndex(index, slotRGBs[x][y], 0);
|
||||||
|
String match = matches.keySet().toArray()[0].toString();
|
||||||
|
File file = new File(fh.InputImagesFolder+fh.fs+match);
|
||||||
|
|
||||||
|
/*
|
||||||
|
BufferedImage plain = new BufferedImage(ia.slotWidth, ia.slotHeight, BufferedImage.TYPE_INT_RGB);
|
||||||
|
Graphics2D g2 = (Graphics2D) plain.getGraphics();
|
||||||
|
g2.setColor(new Color(slotRGBs[x][y]));
|
||||||
|
g2.fillRect(0, 0, plain.getWidth(), plain.getHeight());
|
||||||
|
g2.dispose();
|
||||||
|
ia.placeImage(x, y, plain);
|
||||||
|
*/
|
||||||
|
BufferedImage img;
|
||||||
|
if(!fileHolder.contains(file)){
|
||||||
|
fileHolder.add(file);
|
||||||
|
img = fh.loadImage(file);
|
||||||
|
imgHolder.add(img);
|
||||||
|
}else{
|
||||||
|
int i = fileHolder.indexOf(file);
|
||||||
|
img = imgHolder.get(i);
|
||||||
|
}
|
||||||
|
ia.placeImage(x, y, img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.log(LogLevel.Info, "Finished matching. Output is done ...");
|
||||||
|
fh.saveImage(ia.canvas, new File(fh.OutputFolder+fh.fs+outputName+"-"+fh.OutputFolder.listFiles().length+".png"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args){
|
||||||
|
new Mosaic();
|
||||||
|
}
|
||||||
|
}
|
@ -1,67 +0,0 @@
|
|||||||
package peery.picture;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.awt.image.ColorModel;
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import peery.file.FileHandler;
|
|
||||||
import peery.log.Log;
|
|
||||||
import peery.log.LogLevel;
|
|
||||||
|
|
||||||
public class Classifier {
|
|
||||||
|
|
||||||
public BufferedImage target;
|
|
||||||
|
|
||||||
public Classifier(FileHandler fh){
|
|
||||||
BufferedImage target = fh.loadImage(fh.TargetImageFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void rasterizeTarget(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Plain calculation of average Color of an Image via RGB.
|
|
||||||
* Takes average of RGB values of each pixel.
|
|
||||||
* Does not account for alpha.
|
|
||||||
* @param img Image to process
|
|
||||||
* @param alphaThreshhold value under which pixels are discarded
|
|
||||||
* @return RGB value of the average color
|
|
||||||
*/
|
|
||||||
public int classifyImage(BufferedImage img, File file, int alphaTreshhold){
|
|
||||||
int width = img.getWidth();
|
|
||||||
int height = img.getHeight();
|
|
||||||
Log.log(LogLevel.Debug, "Starting classification of "+file.getPath()+" with width:"+
|
|
||||||
width+" and height:"+height+" ...");
|
|
||||||
|
|
||||||
ColorModel cm = ColorModel.getRGBdefault();
|
|
||||||
float red = 0, green = 0, blue = 0;
|
|
||||||
int pixels = 0;
|
|
||||||
for(int x = 0; x < img.getWidth(); x++){
|
|
||||||
for(int y = 0; y < img.getHeight(); y++){
|
|
||||||
int rgb = img.getRGB(x, y);
|
|
||||||
red += cm.getRed(rgb);
|
|
||||||
blue += cm.getBlue(rgb);
|
|
||||||
green += cm.getGreen(rgb);
|
|
||||||
pixels++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
red = red/pixels;
|
|
||||||
green = green/pixels;
|
|
||||||
blue = blue/pixels;
|
|
||||||
int rgb = new Color((int)red, (int)green, (int)blue).getRGB();
|
|
||||||
Log.log(LogLevel.Debug, "Classified "+file.getPath()+" with following rgb result: value:"+rgb+
|
|
||||||
" red:"+red+", green:"+green+", blue:"+blue);
|
|
||||||
return rgb;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args){
|
|
||||||
FileHandler fh = new FileHandler("/home/peery/Software_Projects/EclipseWorkspace/Picture Mosaic/resources");
|
|
||||||
BufferedImage[] bfs = fh.loadAllImages();
|
|
||||||
Classifier cl = new Classifier(fh);
|
|
||||||
cl.classifyImage(bfs[0], new File("DEBUG_VALUE"), 30);
|
|
||||||
System.out.println(fh.loadBiggestDimension());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,238 @@
|
|||||||
|
package peery.picture;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.ColorModel;
|
||||||
|
import java.io.File;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import peery.file.FileHandler;
|
||||||
|
import peery.log.Log;
|
||||||
|
import peery.log.LogLevel;
|
||||||
|
|
||||||
|
public class ImageAnalyzer {
|
||||||
|
|
||||||
|
public BufferedImage target;
|
||||||
|
private FileHandler fh;
|
||||||
|
|
||||||
|
private Dimension /*biggestInputSize,*/ targetSize;
|
||||||
|
public int slotWidth, slotHeight, slotX, slotY;
|
||||||
|
public BufferedImage canvas;
|
||||||
|
|
||||||
|
public ImageAnalyzer(FileHandler fh){
|
||||||
|
this.fh = fh;
|
||||||
|
this.target = fh.loadImage(fh.TargetImageFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rasterizeTarget(int gridX, int gridY, float targetSizeMultiplier, double gridErrorThresh, int adaptionThreshhold, double adaptionStep){
|
||||||
|
Log.log(LogLevel.Info, "Rasterizing target image ...");
|
||||||
|
Log.log(LogLevel.Info, "Aiming for "+gridX+"*"+gridY+"="+(gridX*gridY)+" tiles ...");
|
||||||
|
//this.biggestInputSize = this.fh.loadBiggestDimension();
|
||||||
|
this.targetSize = new Dimension(this.target.getWidth(), this.target.getHeight());
|
||||||
|
|
||||||
|
//TMP
|
||||||
|
int count = 0;
|
||||||
|
DecimalFormat df = new DecimalFormat("#");
|
||||||
|
while(true){
|
||||||
|
double realSlotWidth = ((targetSize.width*targetSizeMultiplier)/gridX);
|
||||||
|
double realSlotHeight = ((targetSize.height*targetSizeMultiplier)/gridY);
|
||||||
|
Log.log(LogLevel.Debug, "Perfect slot Size would be "+realSlotWidth+"x"+realSlotHeight);
|
||||||
|
double widthLoss = Math.abs(realSlotWidth - Double.parseDouble(df.format(realSlotWidth)));
|
||||||
|
double heightLoss = Math.abs(realSlotHeight - Double.parseDouble(df.format(realSlotHeight)));
|
||||||
|
if(widthLoss > gridErrorThresh || heightLoss > gridErrorThresh){
|
||||||
|
Log.log(LogLevel.Critical, "Grid misplacement error exceeded threshhold! Error is width:"+widthLoss+" height:"+heightLoss);
|
||||||
|
if(widthLoss > gridErrorThresh){
|
||||||
|
gridX *= adaptionStep;
|
||||||
|
}
|
||||||
|
if(heightLoss > gridErrorThresh){
|
||||||
|
gridY *= adaptionStep;
|
||||||
|
}
|
||||||
|
Log.log(LogLevel.Info, "This is the "+(++count)+". adaption to ease the error.");
|
||||||
|
Log.log(LogLevel.Info, "Aiming for "+gridX+"*"+gridY+"="+(gridX*gridY)+" tiles ...");
|
||||||
|
if(count > adaptionThreshhold){
|
||||||
|
Log.log(LogLevel.Critical, "Could not adapt to grid misplacement error! The result might be cut off or missing parts!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}else{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
slotWidth = (int) ((targetSize.width*targetSizeMultiplier)/gridX);
|
||||||
|
slotHeight = (int) ((targetSize.height*targetSizeMultiplier)/gridY);
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
Log.log(LogLevel.Debug, "Target will be "+(int)(targetSize.width*targetSizeMultiplier)
|
||||||
|
+"x"+(int)(targetSize.height*targetSizeMultiplier)+" big.");
|
||||||
|
Log.log(LogLevel.Debug, "Slots are "+slotWidth+"x"+slotHeight+" big.");
|
||||||
|
slotX = gridX;
|
||||||
|
slotY = gridY;
|
||||||
|
//ia.slotWidth*gridX+"x"+ia.slotHeight*gridY
|
||||||
|
//canvas = new BufferedImage((int)(targetSize.getWidth()*targetSizeMultiplier), (int)(targetSize.getHeight()*targetSizeMultiplier), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
canvas = new BufferedImage(slotWidth*gridX, slotHeight*gridY, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D g2 = (Graphics2D) canvas.getGraphics();
|
||||||
|
g2.setColor(Color.BLACK);
|
||||||
|
g2.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares the given rgb value with the index and returns a HashMap of the closest hits.
|
||||||
|
* Unlikely to yield more than 1 result without deviationPercentage
|
||||||
|
* @param index
|
||||||
|
* @param rgb
|
||||||
|
* @param deviation How much the matches can be different from the perfect match, and still be taken.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public HashMap<String, Integer> matchClosestIndex(HashMap<String, Integer> index, int rgb, int deviation){
|
||||||
|
Log.log(LogLevel.Debug, "Searching for closest match for rgb:"+rgb+" in the index with deviation of "+deviation+".");
|
||||||
|
assert(deviation < 100 && 0 <= deviation);
|
||||||
|
if(index == null){
|
||||||
|
Log.log(LogLevel.Critical, "No Index was given for rgb matching. Loading it from file ...");
|
||||||
|
index = this.fh.loadIndex();
|
||||||
|
}
|
||||||
|
HashMap<String, Double> metrics = new HashMap<String, Double>();
|
||||||
|
double currBest = -1;
|
||||||
|
for(String key: index.keySet()){
|
||||||
|
double metric = getMetric(index.get(key), rgb);
|
||||||
|
metrics.put(key, metric);
|
||||||
|
if(currBest > metric || currBest == -1){
|
||||||
|
currBest = metric;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.log(LogLevel.Info, "Calculated all metrics for rgb:"+rgb+" !");
|
||||||
|
|
||||||
|
HashMap<String, Integer> matches = new HashMap<String, Integer>();
|
||||||
|
for(String key: metrics.keySet()){
|
||||||
|
if(metrics.get(key) == currBest || metrics.get(key) < currBest+(currBest*(deviation/(double)100))){
|
||||||
|
matches.put(key, index.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.log(LogLevel.Debug, "Grabbed all good matches for rgb:"+rgb+" ! Got "+matches.size()+" ...");
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the euclidian metric of two given rgb values.
|
||||||
|
* @param rgb1
|
||||||
|
* @param rgb2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private double getMetric(int rgb1, int rgb2){
|
||||||
|
ColorModel cm = ColorModel.getRGBdefault();
|
||||||
|
double result = Math.sqrt(Math.pow((cm.getRed(rgb1)-cm.getRed(rgb2)), 2)+
|
||||||
|
Math.pow(cm.getGreen(rgb1)-cm.getGreen(rgb2), 2)+
|
||||||
|
Math.pow(cm.getBlue(rgb1)-cm.getBlue(rgb2), 2));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Places the given input in its specified slot (gridX, gridY) on the canvas.
|
||||||
|
* Assumes and checks boundaries calculated by rasterizeTarget().
|
||||||
|
* @param gridX
|
||||||
|
* @param gridY
|
||||||
|
* @param input
|
||||||
|
* @param canvas
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public void placeImage(int gridX, int gridY, BufferedImage input){
|
||||||
|
assert(gridX < slotX && gridY < slotY);
|
||||||
|
assert(input.getWidth() < slotWidth && input.getHeight() < slotHeight);
|
||||||
|
|
||||||
|
Graphics2D g2 = (Graphics2D)canvas.getGraphics();
|
||||||
|
g2.drawImage(input, gridX*slotWidth, gridY*slotHeight, slotWidth, slotHeight, null);
|
||||||
|
g2.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plain calculation of average Color of an Image via RGB.
|
||||||
|
* Takes average of RGB values of each pixel.
|
||||||
|
* Does not account for alpha.
|
||||||
|
* @param img Image to process
|
||||||
|
* @param alphaThreshhold value under which pixels are discarded
|
||||||
|
* @return RGB value of the average color
|
||||||
|
*/
|
||||||
|
public int classifyImage(BufferedImage img, File file, int alphaTreshhold){
|
||||||
|
int width = img.getWidth();
|
||||||
|
int height = img.getHeight();
|
||||||
|
Log.log(LogLevel.Debug, "Starting classification of "+file.getName()+" with width:"+
|
||||||
|
width+" and height:"+height+" ...");
|
||||||
|
|
||||||
|
ColorModel cm = ColorModel.getRGBdefault();
|
||||||
|
float red = 0, green = 0, blue = 0;
|
||||||
|
int pixels = 0;
|
||||||
|
for(int x = 0; x < img.getWidth(); x++){
|
||||||
|
for(int y = 0; y < img.getHeight(); y++){
|
||||||
|
int rgb = img.getRGB(x, y);
|
||||||
|
red += cm.getRed(rgb);
|
||||||
|
blue += cm.getBlue(rgb);
|
||||||
|
green += cm.getGreen(rgb);
|
||||||
|
pixels++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
red = red/pixels;
|
||||||
|
green = green/pixels;
|
||||||
|
blue = blue/pixels;
|
||||||
|
int rgb = new Color((int)red, (int)green, (int)blue).getRGB();
|
||||||
|
Log.log(LogLevel.Info, "Classified "+file.getPath()+" with following rgb result: value:"+rgb+
|
||||||
|
" red:"+red+", green:"+green+", blue:"+blue);
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int classifySlot(int gridX, int gridY, BufferedImage target){
|
||||||
|
int slotWidth = target.getWidth()/slotX,
|
||||||
|
slotHeight = target.getHeight()/slotY;
|
||||||
|
BufferedImage subImage = target.getSubimage(gridX*slotWidth, gridY*slotHeight, slotWidth, slotHeight);
|
||||||
|
Log.log(LogLevel.Debug, "Slicing slot "+gridX+"x"+gridY+" out of the target for classification ...");
|
||||||
|
ColorModel cm = ColorModel.getRGBdefault();
|
||||||
|
float red = 0, green = 0, blue = 0;
|
||||||
|
int pixels = 0;
|
||||||
|
for(int x = 0; x < subImage.getWidth(); x++){
|
||||||
|
for(int y = 0; y < subImage.getHeight(); y++){
|
||||||
|
int rgb = subImage.getRGB(x, y);
|
||||||
|
red += cm.getRed(rgb);
|
||||||
|
green += cm.getGreen(rgb);
|
||||||
|
blue += cm.getBlue(rgb);
|
||||||
|
pixels++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
red = red/pixels;
|
||||||
|
green = green/pixels;
|
||||||
|
blue = blue/pixels;
|
||||||
|
int rgb = new Color((int)red, (int)green, (int)blue).getRGB();
|
||||||
|
Log.log(LogLevel.Debug, "Classified slot "+gridX+"x"+gridY+" with following rgb result: value:"+rgb+
|
||||||
|
" red:"+red+", green:"+green+", blue:"+blue);
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
public static void main(String[] args){
|
||||||
|
System.out.println("ZHE DEBUG");
|
||||||
|
/*
|
||||||
|
FileHandler fh = new FileHandler("/home/peery/Software_Projects/EclipseWorkspace/Picture Mosaic/resources");
|
||||||
|
ImageAnalyzer ia = new ImageAnalyzer(fh);
|
||||||
|
|
||||||
|
HashMap<String, Integer> index = fh.loadIndex();
|
||||||
|
for(File f: fh.InputImagesFolder.listFiles()){
|
||||||
|
BufferedImage img = fh.loadImage(f);
|
||||||
|
if(img == null){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int indexValue = ia.classifyImage(img, f, 30);
|
||||||
|
fh.appendToIndex(index, f, indexValue);
|
||||||
|
}
|
||||||
|
index = fh.loadIndex();
|
||||||
|
System.out.println(index.get("Peery-sketch.png"));
|
||||||
|
System.out.println(index.get("rasd"));
|
||||||
|
System.out.println(index.get("Larry the Tiger - Candy Shop Logo (Gift).png"));
|
||||||
|
System.out.println(ia.matchClosestIndex(index, -10744103, 5));
|
||||||
|
//BufferedImage img = ImageUtils.resizeImage(fh.loadImage(fh.InputImagesFolder.listFiles()[0]), new Dimension(500, 300), false);
|
||||||
|
//fh.saveImage(img, new File("/home/peery/Software_Projects/EclipseWorkspace/Picture Mosaic/resources/resize-test.png"));
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package peery.picture;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
public class ImageUtils {
|
||||||
|
|
||||||
|
public static BufferedImage resizeImage(BufferedImage input, Dimension targetSize, boolean keepRatio){
|
||||||
|
Image tmp;
|
||||||
|
BufferedImage img;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
if(targetSize.getWidth() > targetSize.getHeight()){
|
||||||
|
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{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue