Initial commit 10.3
parent
27fb4e14c5
commit
51328f56cb
@ -0,0 +1,59 @@
|
|||||||
|
package _10._3;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import provided._10._3.ImageFilter;
|
||||||
|
|
||||||
|
public class ImageFilterThreaded extends ImageFilter {
|
||||||
|
|
||||||
|
class FilterThread implements Runnable {
|
||||||
|
private int x1;
|
||||||
|
private int x2;
|
||||||
|
private int y1;
|
||||||
|
private int y2;
|
||||||
|
private Color[][] result;
|
||||||
|
private float[][] filter;
|
||||||
|
|
||||||
|
private FilterThread(int x1, int x2, int y1, int y2, Color[][] result, float[][] filter) {
|
||||||
|
this.x1 = x1;
|
||||||
|
this.x2 = x2;
|
||||||
|
this.y1 = y1;
|
||||||
|
this.y2 = y2;
|
||||||
|
this.result = result;
|
||||||
|
this.filter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (int x = x1; x < x2; x++) {
|
||||||
|
for (int y = y1; y < y2; y++) {
|
||||||
|
filterPixel(result, x, y, filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Color[][] filterMatrix(float[][] filter) {
|
||||||
|
Color[][] result = new Color[matrix.length][matrix[0].length];
|
||||||
|
|
||||||
|
Thread threadLB = new Thread(new FilterThread(0, matrix.length/2, matrix[0].length/2, matrix[0].length,result,filter));
|
||||||
|
Thread threadRB = new Thread(new FilterThread(matrix.length/2, matrix.length, matrix[0].length/2, matrix[0].length,result,filter));
|
||||||
|
Thread threadLT = new Thread(new FilterThread(0, matrix.length/2, 0, matrix[0].length/2,result,filter));
|
||||||
|
Thread threadRT = new Thread(new FilterThread(matrix.length/2, matrix.length, 0, matrix[0].length/2,result,filter));
|
||||||
|
threadLB.start();
|
||||||
|
threadRB.start();
|
||||||
|
threadLT.start();
|
||||||
|
threadRT.start();
|
||||||
|
|
||||||
|
try {
|
||||||
|
threadLB.join();
|
||||||
|
threadRB.join();
|
||||||
|
threadLT.join();
|
||||||
|
threadRT.join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,113 @@
|
|||||||
|
package provided._10._3;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ImageFilter {
|
||||||
|
|
||||||
|
private static final int FILTER_SIZE = 3;
|
||||||
|
private static final int OFFSET = FILTER_SIZE / 2;
|
||||||
|
|
||||||
|
public static final float[][] FILTER_BLUR = new float[][] {
|
||||||
|
{ 0.111f, 0.111f, 0.111f },
|
||||||
|
{ 0.111f, 0.111f, 0.111f },
|
||||||
|
{ 0.111f, 0.111f, 0.111f }
|
||||||
|
};
|
||||||
|
public static final float[][] FILTER_SHARPEN = new float[][] {
|
||||||
|
{ 0.f, -1f, 0.f },
|
||||||
|
{ -1f, 5f, -1f },
|
||||||
|
{ 0.f, -1f, 0.f }
|
||||||
|
};
|
||||||
|
public static final float[][] FILTER_LINES = new float[][] {
|
||||||
|
{ -1f, -1f, -1f },
|
||||||
|
{ -1f, 8f, -1f },
|
||||||
|
{ -1f, -1f, -1f }
|
||||||
|
};
|
||||||
|
|
||||||
|
protected Color[][] matrix = new Color[0][0];
|
||||||
|
|
||||||
|
public void setImage(File input) throws IOException {
|
||||||
|
BufferedImage img = ImageIO.read(input);
|
||||||
|
getMatrix(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applyFilter(float[][] filter, File output) throws IOException, InvalidFilterException {
|
||||||
|
if (filter == null || filter.length != FILTER_SIZE || filter[0].length != FILTER_SIZE) {
|
||||||
|
throw new InvalidFilterException();
|
||||||
|
}
|
||||||
|
Color[][] result = filterMatrix(filter);
|
||||||
|
BufferedImage img = new BufferedImage(result.length, result[0].length, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
setMatrix(img, result);
|
||||||
|
ImageIO.write(img, "jpg", output);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Color[][] filterMatrix(float[][] filter) {
|
||||||
|
Color[][] result = new Color[matrix.length][matrix[0].length];
|
||||||
|
for (int x = 0; x < matrix.length; x++) {
|
||||||
|
for (int y = 0; y < matrix[x].length; y++) {
|
||||||
|
filterPixel(result, x, y, filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void filterPixel(Color[][] result, int x, int y, float[][] filter) {
|
||||||
|
Color[][] colors = getColorMatrix(x, y);
|
||||||
|
float red = 0;
|
||||||
|
float green = 0;
|
||||||
|
float blue = 0;
|
||||||
|
for (int i = 0; i < FILTER_SIZE; i++) {
|
||||||
|
for (int j = 0; j < FILTER_SIZE; j++) {
|
||||||
|
red += (float) colors[i][j].getRed() * filter[i][j];
|
||||||
|
green += (float) colors[i][j].getGreen() * filter[i][j];
|
||||||
|
blue += (float) colors[i][j].getBlue() * filter[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
red = Math.min(red, 255);
|
||||||
|
red = Math.max(red, 0);
|
||||||
|
green = Math.min(green, 255);
|
||||||
|
green = Math.max(green, 0);
|
||||||
|
blue = Math.min(blue, 255);
|
||||||
|
blue = Math.max(blue, 0);
|
||||||
|
result[x][y] = new Color(Math.round(red), Math.round(green), Math.round(blue));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Color[][] getColorMatrix(int x, int y) {
|
||||||
|
Color[][] result = new Color[FILTER_SIZE][FILTER_SIZE];
|
||||||
|
for (int i = 0; i < FILTER_SIZE; i++) {
|
||||||
|
for (int j = 0; j < FILTER_SIZE; j++) {
|
||||||
|
result[i][j] = getColor(x + (i - OFFSET), y + (j - OFFSET));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Color getColor(int x, int y) {
|
||||||
|
x = Math.min(x, matrix.length - 1);
|
||||||
|
x = Math.max(x, 0);
|
||||||
|
y = Math.min(y, matrix[0].length - 1);
|
||||||
|
y = Math.max(y, 0);
|
||||||
|
return matrix[x][y];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMatrix(BufferedImage img, Color[][] matrix) {
|
||||||
|
for (int x=0;x<matrix.length;x++) {
|
||||||
|
for (int y=0;y<matrix[x].length;y++) {
|
||||||
|
img.setRGB(x, y, matrix[x][y].getRGB());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getMatrix(BufferedImage img) {
|
||||||
|
matrix = new Color[img.getWidth()][img.getHeight()];
|
||||||
|
for (int x=0;x<img.getWidth();x++) {
|
||||||
|
for (int y=0;y<img.getHeight();y++) {
|
||||||
|
matrix[x][y] = new Color(img.getRGB(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
package provided._10._3;
|
||||||
|
|
||||||
|
import _10._3.ImageFilterThreaded;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ImageFilterTest {
|
||||||
|
|
||||||
|
private static final int REPETITIONS = 5;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
ImageFilter filterSequential = new ImageFilter();
|
||||||
|
ImageFilter filterThreaded = new ImageFilterThreaded();
|
||||||
|
try {
|
||||||
|
filterSequential.setImage(new File("./university_of_oldenburg.jpg"));
|
||||||
|
filterThreaded.setImage(new File("./university_of_oldenburg.jpg"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long start;
|
||||||
|
long stop;
|
||||||
|
long time;
|
||||||
|
start = System.nanoTime();
|
||||||
|
for (int i = 0; i < REPETITIONS; i++) {
|
||||||
|
runFilters(filterSequential);
|
||||||
|
}
|
||||||
|
stop = System.nanoTime();
|
||||||
|
time = (stop - start) / 1000000L;
|
||||||
|
System.out.println("Sequential runtime: " + time + " ms");
|
||||||
|
start = System.nanoTime();
|
||||||
|
for (int i = 0; i < REPETITIONS; i++) {
|
||||||
|
runFilters(filterThreaded);
|
||||||
|
}
|
||||||
|
stop = System.nanoTime();
|
||||||
|
time = (stop - start) / 1000000L;
|
||||||
|
System.out.println("Threaded runtime: " + time + " ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runFilters(ImageFilter filter) {
|
||||||
|
try {
|
||||||
|
filter.applyFilter(ImageFilter.FILTER_BLUR, new File("./university_of_oldenburg_blur.jpg"));
|
||||||
|
filter.applyFilter(ImageFilter.FILTER_SHARPEN, new File("./university_of_oldenburg_sharpen.jpg"));
|
||||||
|
filter.applyFilter(ImageFilter.FILTER_LINES, new File("./university_of_oldenburg_lines.jpg"));
|
||||||
|
} catch (IOException | InvalidFilterException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package provided._10._3;
|
||||||
|
|
||||||
|
public class InvalidFilterException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue