diff --git a/src/main/java/_10/_3/ImageFilterThreaded.java b/src/main/java/_10/_3/ImageFilterThreaded.java new file mode 100644 index 0000000..ce84507 --- /dev/null +++ b/src/main/java/_10/_3/ImageFilterThreaded.java @@ -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; + } + +} diff --git a/src/main/java/provided/_10/_3/ImageFilter.java b/src/main/java/provided/_10/_3/ImageFilter.java new file mode 100644 index 0000000..80176cb --- /dev/null +++ b/src/main/java/provided/_10/_3/ImageFilter.java @@ -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