-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathImageFilter.java
More file actions
229 lines (204 loc) · 7.44 KB
/
ImageFilter.java
File metadata and controls
229 lines (204 loc) · 7.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.*;
import java.io.*;
public class ImageFilter {
private Random rand = new Random();
private File f;
private BufferedImage image;
private int width;
private int height;
private String tag;
private final int overallColorThreshold = 45; //60
private final int ALPHA_VALUE = 255; //fully opaque
public ImageFilter(File f, String tag) {
this.f = f;
System.out.println("Reading file: "+f);
image = ImageUtilities.readImage(f);
width = image.getWidth();
height = image.getHeight();
this.tag = tag;
}
//red colors: Red (#D30000; 211,0,0)
public void applyCustomFilter() {
System.out.println("Applying custom filter...");
Color blackC = new Color(0, 0, 0);
int blackRGB = blackC.getRGB();
Color whiteC = new Color(255, 255, 255);
int whiteRGB = whiteC.getRGB();
for(int r = 0; r < height; r++) {
for(int c = 0; c < width; c++) {
Color color = new Color(image.getRGB(c, r));
int colorRGB = color.getRGB();
Color redColor = new Color(255, 0, 0);
if(colorRGB != whiteRGB && colorRGB != blackRGB) {
image.setRGB(c, r, redColor.getRGB());
}
}
}
}
public void applyBlackAndWhite() {
System.out.println("Applying black and white filter...");
for(int r = 0; r < height; r++) { // 'r' corresponds to 'y'
for(int c = 0; c < width; c++) { // 'c' corresponds to 'x'
Color color = new Color(image.getRGB(c, r));
int luminance = getLuminance(color);
color = new Color(luminance, luminance, luminance, ALPHA_VALUE);
image.setRGB(c, r, color.getRGB());
}
}
}
private int getLuminance(Color c) {
final int RED_LUMINANCE_COEFFICIENT = 30;
final int GREEN_LUMINANCE_COEFFICIENT = 59;
final int BLUE_LUMINANCE_COEFFICIENT = 11;
int luminance = (RED_LUMINANCE_COEFFICIENT * c.getRed() + GREEN_LUMINANCE_COEFFICIENT * c.getGreen() + BLUE_LUMINANCE_COEFFICIENT * c.getBlue()) / (RED_LUMINANCE_COEFFICIENT + GREEN_LUMINANCE_COEFFICIENT + BLUE_LUMINANCE_COEFFICIENT);
return luminance;
}
public void applySepia() {
System.out.println("Applying sepia filter...");
final int adjustRed = 16;
final int adjustGreen = -3;
final int adjustBlue = -30;
for(int r = 0; r < height; r++) { // 'r' corresponds to 'y'
for(int c = 0; c < width; c++) { // 'c' corresponds to 'x'
Color color = new Color(image.getRGB(c, r));
int luminance = getLuminance(color);
int red = truncateValues(luminance + adjustRed);
int green = truncateValues(luminance + adjustGreen);
int blue = truncateValues(luminance + adjustBlue);
color = new Color(red, green, blue, ALPHA_VALUE);
image.setRGB(c, r, color.getRGB());
}
}
updateTag("SEPIA"); //applies tag of "SEPIA"
}
// 'p' determines how far from the center to start fading the pixels; 'p' has a range of 0.0 - 1.0
public void applyVignette(double p) {
System.out.println("Applying vignette...");
// center coordinates:
int cx = width / 2;
int cy = height / 2;
// constants:
double xp2 = Math.pow(cx, 2);
double yp2 = Math.pow(cy, 2);
double threshold = Math.pow(p, 2);
// processing:
for(int r = 0; r < height; r++) { // 'r' corresponds to 'y'
for(int c = 0; c < width; c++) { // 'c' corresponds to 'x'
Color color = new Color(image.getRGB(c, r));
double d = (Math.pow((cx - c), 2) / xp2) + (Math.pow((cy - r), 2) / yp2);
if(d > 1.0) { // if pixel is located outside of the ellipse
color = new Color(0, 0, 0, ALPHA_VALUE);
}
else if(d > threshold) { //if the pixel is located in the faded area
double fade = 1 - Math.pow((d - threshold) / (1 - threshold), 2);
int red = (int)(color.getRed() * fade);
int green = (int)(color.getGreen() * fade);
int blue = (int)(color.getBlue() * fade);
color = new Color(red, green, blue, ALPHA_VALUE);
}
else{
color = new Color(color.getRed(), color.getGreen(), color.getBlue(), ALPHA_VALUE);
}
image.setRGB(c, r, color.getRGB());
}
}
updateTag("VIGNETTE"); //applies tag of "VIGNETTE" or "VIGNETTE_BW" when combined w/ BW filter or "VIGNETTE_SEPIA" when combined w/ vignette filter
}
/*
* Splits image into 3x3
*
* | 1 2 3 |
* | 4 5 6 |
* | 7 8 9 |
*/
public void split3x3(int x, int y, int pxSize) {
if(x + pxSize >= width || y + pxSize >= height) {
System.out.println("FAILED SPLIT!");
return;
}
BufferedImage[] splitImages = new BufferedImage[9];
int divSize = pxSize / 3;
for(int i = 0; i < 9; i++) {
splitImages[i] = image.getSubimage(x + (i % 3) * divSize, y + (i / 3) * divSize, divSize, divSize);
System.out.println("Writing file: "+splitImages[i]);
ImageUtilities.writeImage(splitImages[i], f, "split"+(i+1));
}
System.out.println("Split complete.");
}
/*
* For scrolling images
*/
public void split1xN(int x, int y, int pxSize, int N) {
if(x + pxSize >= width || y + pxSize >= height) {
System.out.println("FAILED SPLIT!");
return;
}
BufferedImage[] splitImages = new BufferedImage[9];
int divSize = pxSize / 3;
for(int i = 0; i < 9; i++) {
splitImages[i] = image.getSubimage(x + (i % 3) * divSize, y + (i / 3) * divSize, divSize, divSize);
System.out.println("Writing file: "+splitImages[i]);
ImageUtilities.writeImage(splitImages[i], f, "split"+(i+1));
}
System.out.println("Split complete.");
}
public void addBorders() {
int newSize;
if(width > height) newSize = width;
else newSize = height;
BufferedImage newImage = new BufferedImage(newSize, newSize, 5);
for(int r = 0; r < newSize; r++) {
for(int c = 0; c < newSize; c++) { // c < width
newImage.setRGB(c, r, 0);
}
}
for(int r = 0; r < height; r++) {
for(int c = 0; c < width; c++) { // c < width
newImage.setRGB(c + (newSize - width) / 2, r + (newSize - height) / 2, image.getRGB(c, r));
}
}
System.out.println("Writing file: "+newImage);
ImageUtilities.writeImage(newImage, f, "bordered");
}
// truncates negative values to zero
// truncates positive values that exceed 255 to 255
// doesn't affect positive values in the inclusive range of 0-255
private int truncateValues(int num) {
if(num < 0)
return 0;
else if(num > 255)
return 255;
else
return num;
}
private void updateTag(String attribute) {
//attribute will be: 'BW', 'SEPIA', or 'VIGNETTE'
if(tag == "") { //when tag is empty
tag = attribute;
}
else{ //when tag is NOT empty
// an image will never have both SEPIA and BW
switch(attribute) {
case "BW":
tag += "_BW";
break;
case "SEPIA":
tag += "_SEPIA";
break;
case "VIGNETTE":
tag = "VIGNETTE_"+tag;
break;
default: //unlikely to happen
tag = "ORIGINAL";
break;
}
}
}
public void write() {
System.out.println("Writing file: "+f);
ImageUtilities.writeImage(image, f, tag);
}
}