-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHelpers.java
More file actions
308 lines (263 loc) · 9 KB
/
Copy pathHelpers.java
File metadata and controls
308 lines (263 loc) · 9 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
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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
package qr;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public final class Helpers {
//TODO modify PATH_HEADER if images do not load properly
private static final String SEP = File.separator;
private static final String PATH_HEADER = "images" + SEP;
private static final int BACKGROUND_COLOR = -1;
private static final int SCALE = 10;
private static final int BORDER = 4*SCALE; //quiet zone is 4 module large
private static final int GREEN_BLACK = 0xFF_00_60_00;
private static final int GREEN_WHITE = 0xFF_90_FF_90;
private static final int RED = 0xFF_80_00_00;
/**
* compare a matrix loaded from file with a 2D-array given in arguments.
* @param matrix the 2-dimensional array
* @param imagePath the path of the image to compare with the matrix
* @return true if the 2 images are similar, false otherwise
*/
public static boolean compare(int [][] matrix,String imagePath) {
int[][] expected= readMatrix(imagePath);
if(expected.length != matrix.length || expected.length!=expected[0].length || matrix.length!=matrix[0].length) {
throw new IllegalArgumentException("The size of the two QR code does not match: matrix:"+matrix.length+" image:"+expected.length);
}
int[][] diff = new int[expected.length][expected.length];
boolean similar = true;
for(int x=0;x<matrix.length;x++) {
for(int y=0;y<matrix.length;y++) {
if(matrix[x][y]!=expected[x][y]) {
diff[x][y] = RED;
similar = false;
}else {
if(expected[x][y]== -1) {
diff[x][y] = GREEN_WHITE;
}else if(expected[x][y]== -16777216){
diff[x][y] = GREEN_BLACK;
}
}
}
}
BufferedImage imageExpected = scale(expected, SCALE, BORDER/2);
BufferedImage imageGiven = scale(matrix, SCALE, BORDER/2);
BufferedImage imagediff = scale(diff, SCALE, BORDER/2);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame editorFrame = new JFrame("Compare with "+imagePath);
editorFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
ImageIcon imageIcon1 = new ImageIcon(imageExpected);
JLabel jLabel1 = new JLabel(imageIcon1);
JPanel pane1 = new JPanel(new BorderLayout());
JLabel text1 = new JLabel("Expected matrix");
text1.setHorizontalAlignment(SwingConstants.CENTER);
text1.setFont(new Font("",Font.PLAIN, 24));
pane1.add(jLabel1,BorderLayout.SOUTH);
pane1.add(text1,BorderLayout.NORTH);
ImageIcon imageIcon2 = new ImageIcon(imagediff);
JLabel jLabel2 = new JLabel();
jLabel2.setIcon(imageIcon2);
jLabel2.setHorizontalAlignment(SwingConstants.CENTER);
JPanel pane2 = new JPanel(new BorderLayout());
JLabel text2 = new JLabel("Difference between the 2 images");
text2.setHorizontalAlignment(SwingConstants.CENTER);
text2.setFont(new Font("",Font.PLAIN, 24));
pane2.add(jLabel2,BorderLayout.SOUTH);
pane2.add(text2,BorderLayout.NORTH);
ImageIcon imageIcon3 = new ImageIcon(imageGiven);
JLabel jLabel3 = new JLabel();
jLabel3.setIcon(imageIcon3);
JPanel pane3 = new JPanel(new BorderLayout());
JLabel text3 = new JLabel("Your result");
text3.setHorizontalAlignment(SwingConstants.CENTER);
text3.setFont(new Font("",Font.PLAIN, 24));
pane3.add(jLabel3,BorderLayout.SOUTH);
pane3.add(text3,BorderLayout.NORTH);
editorFrame.getContentPane().add(pane1, BorderLayout.WEST);
editorFrame.getContentPane().add(pane2, BorderLayout.SOUTH);
editorFrame.getContentPane().add(pane3, BorderLayout.EAST);
editorFrame.pack();
editorFrame.setLocationRelativeTo(null);
editorFrame.setVisible(true);
}
});
return similar;
}
/**
* Shows a matrix in a new window. The matrix is scaled for visualization
*
* @param matrix
* @param scale
*/
public static void show(int[][] matrix, int scale) {
BufferedImage qrCode = Helpers.matrixToImage(matrix);
BufferedImage image = reshape(qrCode, scale, 4*scale);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame editorFrame = new JFrame("QR Code");
editorFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
ImageIcon imageIcon = new ImageIcon(image);
JLabel jLabel = new JLabel();
jLabel.setIcon(imageIcon);
editorFrame.getContentPane().add(jLabel, BorderLayout.CENTER);
editorFrame.pack();
editorFrame.setLocationRelativeTo(null);
editorFrame.setVisible(true);
}
});
}
/**
* Read an image from a file in the images directory and return the matrix
* associated to it
*
* @param name
* The name of the image
* @return The loaded matrix of the image
*/
public static int[][] readMatrix(String name) {
return imageToMatrix(Helpers.read(name));
}
/**
* Write the matrix into an image file
* @param name
* the name of the file
* @param matrix
* the matrix to write
*/
public static void writeMatrix(String name, int[][] matrix) {
write(name, matrixToImage(matrix));
}
/*
* ================================================
* PRIVATE METHODS
* Cannot be used.
* ================================================
*/
/**
* Transform an image into a 2 dimensional array with the corresponding pixel
*
* @param image
* the image to be transformed into an array
* @return the matrix of the image
*/
private static int[][] imageToMatrix(BufferedImage image) {
int[][] matrix = new int[image.getWidth()][image.getHeight()];
for (int i = 0; i < image.getWidth(); i++) {
for (int j = 0; j < image.getHeight(); j++) {
matrix[i][j] = image.getRGB(i, j);
}
}
return matrix;
}
/**
* Transform a 2 dimensional int array into an image
*
* @param matrix
* the 2-dimensional array representing the QR code
* @return The image of the QR code
*/
private static BufferedImage matrixToImage(int[][] matrix) {
BufferedImage image = new BufferedImage(matrix.length, matrix[0].length, BufferedImage.TYPE_INT_ARGB);
for (int x = 0; x < matrix.length; x++) {
for (int y = 0; y < matrix[0].length; y++) {
image.setRGB(x, y, matrix[x][y]);
}
}
return image;
}
/**
* Write an image on a file
* @param name
* the name of the file
* @param image
* the image to write on disk
*/
private static void write(String name, BufferedImage image) {
String projectPath = System.getProperty("user.dir");
try {
// Output file path
String path = projectPath + SEP + PATH_HEADER + name;
if (!name.contains(".png")) {
path = path + ".png";
}
File output_file = new File(path);
// Writing to file taking type and path as
ImageIO.write(image, "png", output_file);
//System.out.println("Writing complete.");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Read an Image from a file from the images directory
*
* @param name
* The name of the image
* @return The loaded image
*/
private static BufferedImage read(String name) {
String projectPath = System.getProperty("user.dir");
String path = projectPath + SEP + PATH_HEADER + name;
try {
if (!name.contains(".png")) {
path = path + ".png";
}
File pathToFile = new File(path);
BufferedImage image = ImageIO.read(pathToFile);
return image;
} catch (IOException ex) {
ex.printStackTrace();
throw new IllegalArgumentException("The image '"+path+"' does not exist or could not load");
}
}
private static BufferedImage scale(int[][] image, int scale, int borderSize) {
return reshape(Helpers.matrixToImage(image), scale, borderSize);
}
private static BufferedImage reshape(BufferedImage image, int scale, int borderSize) {
if (image.getHeight() != image.getWidth()) {
throw new IllegalArgumentException("The image must be squared");
}
int previousSize = image.getWidth();
int size = previousSize * scale + borderSize * 2;
BufferedImage ehancedIm = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
/*
* Border
*/
for (int i = 0; i < size; i++) {
for (int j = 0; j < borderSize; j++) {
ehancedIm.setRGB(i, j, BACKGROUND_COLOR);
ehancedIm.setRGB(i, j + size - borderSize, BACKGROUND_COLOR);
if (i >= borderSize && i < size - borderSize) {
ehancedIm.setRGB(j, i, BACKGROUND_COLOR);
ehancedIm.setRGB(j + size - borderSize, i, BACKGROUND_COLOR);
}
}
}
/*
* Scaling
*/
for (int x = 0; x < previousSize; x++) {
for (int y = 0; y < previousSize; y++) {
int color = image.getRGB(x, y);
int startX = x * scale + borderSize;
int startY = y * scale + borderSize;
for (int i = startX; i < startX + scale; i++) {
for (int j = startY; j < startY + scale; j++) {
ehancedIm.setRGB(i, j, color);
}
}
}
}
return ehancedIm;
}
}