-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPixelEffects.java
280 lines (237 loc) · 7.88 KB
/
PixelEffects.java
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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
/* A class to implement the various pixel effects.
* @author kenneth2
*/
public class PixelEffects {
static int width;
static int height;
static int[][] result = new int[width][height];
// public static void readImageMetrics(int[][] source) {
// width = source.length;
// height = source[0].length;
// result = new int[width][height];
// }
/** Copies the source image to a new 2D integer image */
public static int[][] copy(int[][] source) {
width = source.length;
height = source[0].length;
result = new int[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgb = source[i][j];
int red = RGBUtilities.toRed(rgb);
int green = RGBUtilities.toGreen(rgb);
int blue = RGBUtilities.toBlue(rgb);
result[i][j] = RGBUtilities.toRGB(red, green, blue);
}
}
return result;
}
/** Removes "redeye" caused by a camera flash. sourceB is not used */
public static int[][] redeye(int[][] source) {
width = source.length;
height = source[0].length;
result = new int[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgb = source[i][j];
int red = RGBUtilities.toRed(rgb);
int green = RGBUtilities.toGreen(rgb);
int blue = RGBUtilities.toBlue(rgb);
if (red > 4 * Math.max(green, blue) && red > 64)
red = green = blue = 0;
result[i][j] = RGBUtilities.toRGB(red, green, blue);
}
}
return result;
}
/**
* Resize the array image to the new width and height
* You are going to need to figure out how to map between a pixel
* in the destination image to a pixel in the source image
* @param source
* @param newWidth
* @param newHeight
* @return
*/
public static int[][] resize(int[][] source, int newWidth, int newHeight) {
// readImageMetrics(source);
width = source.length;
height = source[0].length;
result = new int[newWidth][newHeight];
for (int i = 0; i < newWidth; i++) {
for (int j = 0; j < newHeight; j++) {
// int rgb = source[i][j];
// int red = RGBUtilities.toRed(rgb);
// int green = RGBUtilities.toGreen(rgb);
// int blue = RGBUtilities.toBlue(rgb);
result[i][j] = source[(i*width) / newWidth][((j*height) / newHeight)];
}
}
// Hints: Use two nested for loops between 0... newWidth-1 and 0.. newHeight-1 inclusive.
// Hint: You can just use relative proportion to calculate the x (or y coordinate) in the original image.
// For example if you're setting a pixel halfway across the image, you should be reading half way across the original image too.
return result;
}
/**
* Create a new image array that is the same dimesions of the reference
* array. The array may be larger or smaller than the source. Hint -
* this methods should be just one line - delegate the work to resize()!
*
* @param source
* the source image
* @param reference
* @return the resized image
*/
// turns source to reference size
public static int[][] resize(int[][] source, int[][] reference) {
width = source.length;
height = source[0].length;
int newWidth = reference.length;
int newHeight = reference[0].length;
result = new int[newWidth][newHeight];
for (int i = 0; i < newWidth; i++) {
for (int j = 0; j < newHeight; j++) {
int rgb = source[(i*width) / newWidth][(j*height) / newHeight];
int red = RGBUtilities.toRed(rgb);
int green = RGBUtilities.toGreen(rgb);
int blue = RGBUtilities.toBlue(rgb);
result[i][j] = RGBUtilities.toRGB(red, green, blue);
}
}
return result;
}
/**
* Half the size of the image. This method should be just one line! Just
* delegate the work to resize()!
*/
public static int[][] half(int[][] source) {
width = source.length;
height = source[0].length;
return resize(source, width / 2, height / 2);
}
/** Flip the image vertically */
public static int[][] flip(int[][] source) {
width = source.length;
height = source[0].length;
result = new int[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgb = source[i][j];
int red = RGBUtilities.toRed(rgb);
int green = RGBUtilities.toGreen(rgb);
int blue = RGBUtilities.toBlue(rgb);
result[i][height - j -1] = RGBUtilities.toRGB(red, green, blue);
}
}
return result;
}
/** Reverse the image horizontally */
public static int[][] mirror(int[][] source) {width = source.length;
height = source[0].length;
result = new int[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgb = source[i][j];
int red = RGBUtilities.toRed(rgb);
int green = RGBUtilities.toGreen(rgb);
int blue = RGBUtilities.toBlue(rgb);
result[width - i - 1][j] = RGBUtilities.toRGB(red, green, blue);
}
}
return result;
}
/** Rotate the image */
public static int[][] rotateLeft(int[][] source) {
width = source.length;
height = source[0].length;
result = new int[height][width];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgb = source[i][j];
int red = RGBUtilities.toRed(rgb);
int green = RGBUtilities.toGreen(rgb);
int blue = RGBUtilities.toBlue(rgb);
result[j][i] = RGBUtilities.toRGB(red, green, blue);
}
}
flip(result);
return result;
}
/** Merge the red,blue,green components from two images */
public static int[][] merge(int[][] sourceA, int[][] sourceB) {
// The output should be the same size as the input. Scale (x,y) values
// when reading the background
// (e.g. so the far right pixel of the source is merged with the
// far-right pixel of the background).
int[][] background = resize(sourceB, sourceA);
width = sourceA.length;
height = sourceA[0].length;
result = new int[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgbA = sourceA[i][j];
int rgbB = background[i][j];
int redA = RGBUtilities.toRed(rgbA);
int greenA = RGBUtilities.toGreen(rgbA);
int blueA = RGBUtilities.toBlue(rgbA);
int redB = RGBUtilities.toRed(rgbB);
int greenB = RGBUtilities.toGreen(rgbB);
int blueB = RGBUtilities.toBlue(rgbB);
int red = (redA + redB) / 2;
int green = (greenA + greenB) / 2;
int blue = (blueA + blueB) / 2;
int average = RGBUtilities.toRGB(red, green, blue);
result[i][j] = average;
}
}
return result;
}
/**
* Replace the green areas of the foreground image with parts of the back
* image
*/
public static int[][] chromaKey(int[][] sourceA, int[][] sourceB) {
if (sourceA.length != sourceB.length || sourceA[0].length != sourceB[0].length) {
sourceA = resize(sourceA, sourceB);
}
width = sourceA.length;
height = sourceA[0].length;
result = new int[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgbA = sourceA[i][j];
int rgbB = sourceB[i][j];
int redA = RGBUtilities.toRed(rgbA);
int greenA = RGBUtilities.toGreen(rgbA);
int blueA = RGBUtilities.toBlue(rgbA);
int redB = RGBUtilities.toRed(rgbB);
int greenB = RGBUtilities.toGreen(rgbB);
int blueB = RGBUtilities.toBlue(rgbB);
if (greenA > 75) {
result[i][j] = RGBUtilities.toRGB(redB, greenB, blueB);
} else result[i][j] = RGBUtilities.toRGB(redA, greenA, blueA);
}
}
return result;
}
//grayscale
public static int[][] funky(int[][] source, int[][] sourceB) {
width = source.length;
height = source[0].length;
result = new int[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgb = source[i][j];
int red = RGBUtilities.toRed(rgb);
int green = RGBUtilities.toGreen(rgb);
int blue = RGBUtilities.toBlue(rgb);
//creates balanced greyscale
double redGreyscale = red * .21;
double greenGreyscale = green * .72;
double blueGreyscale = blue * .07;
result[i][j] = RGBUtilities.toRGB((int)redGreyscale, (int)greenGreyscale, (int)blueGreyscale);
}
}
return result;
}
}