-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathImage.java
More file actions
171 lines (147 loc) · 4.6 KB
/
Image.java
File metadata and controls
171 lines (147 loc) · 4.6 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
package array.bliffoscope;
/**
* Represents a flat two dimensional "text" image. Each pixel of the image
* is represented as a character. A pixel is located by specifying its
* x-coordinate and y-coordinate.
* <p>
* Example 3 x 3 Image:<br />
* abc
* def
* ghi
* <p>
* Coordinate (0,0) points to 'a', while coordinate (2,2) to 'i'.
*/
public class Image {
private String name;
private char[][] pixelGrid;
public Image() {
this( "", null );
}
public Image( char[][] pixelGrid ) {
this( "", pixelGrid );
}
public Image( String name, char[][] pixelGrid ) {
this.name = name;
this.pixelGrid = pixelGrid != null ? pixelGrid : new char[][] {};
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
/**
* @return A non-negative integer that represents the height of the image in pixels.
*/
public int getHeight() {
return pixelGrid.length;
}
/**
* @return A non-negative integer that represents the length of the image in pixels.
*/
public int getLength() {
if( pixelGrid.length > 0 && pixelGrid[ 0 ] != null ) {
return pixelGrid[ 0 ].length;
} else {
return 0;
}
}
/**
* @return A non-negative integer that represents the resolution of the image.
* Resolution is calculated by multiplying height (in pixels) times
* length (in pixels)
*/
public int getResolution() {
return getLength() * getHeight();
}
/**
* @return True if coordinate (x,y) is a valid pixel position within the image boundaries
*
* @see #getPixel(int, int)
*/
public boolean hasPixel( int x, int y ) {
return pixelGrid.length > 0 && y < pixelGrid.length
&& pixelGrid[ 0 ].length > 0 && x < pixelGrid[ 0 ].length;
}
/**
* @throws ArrayIndexOutOfBoundsException if x or y are out of bounds
* @see #hasPixel(int, int)
*/
public char getPixel( int x, int y ) {
return pixelGrid[ y ][ x ];
}
/**
* Compares this image to the provided image. Similarity between images
* is scored on a percentage scale from 0 to 1. 0 meaning not a single
* pixel matched up, while 1 implying the images are equal.
* <p>
* <b>Important Assumption</b>: similarity of images can ONLY be computed
* if both images are of the same dimensions and resolutions. Images
* of different dimensions, will result in a similarity score of -1.
*
* @return -1 if images do not have the same dimensions.
* 0 if the images are completely different (not a single pixel matches).
* 0 < x < 1 percentage score of how similar the images are.
* 1 is a perfect match, images are the same.
*
* @throws NullPointerException if image is null
*/
public double calculateSimilarity( Image image ) {
boolean validImage = this.getLength() == image.getLength()
&& this.getHeight() == image.getHeight() && image.getResolution() > 0;
if( ! validImage ) {
return -1;
}
double matchedPixels = 0;
for( int x = 0; x < image.getLength(); x++ ) {
for( int y = 0; y < image.getHeight(); y++ ) {
if( this.getPixel(x, y) == image.getPixel(x, y) ) {
matchedPixels++;
}
}
}
return matchedPixels / (double)image.getResolution();
}
/**
* @return A subset image which was created at point (startX, startY) with
* specified length and height. If the coordinates are invalid or
* the length/height too long then an empty non-null image is returned.
*
* @throws java.lang.NegativeArraySizeException if length or height are negative
*/
public Image createSubset( int startX, int startY, int length, int height ) {
int endX = startX + length - 1;
int endY = startY + height - 1;
if( ! hasPixel(startX, startY) || ! hasPixel(endX, endY) ) {
return new Image();
}
char[][] subset = new char[ height ][ length ];
for( int y = 0; y < height; y++ ) {
for( int x = 0; x < length; x++ ) {
subset[ y ][ x ] = getPixel( startX + x, startY + y );
}
}
return new Image( subset );
}
@Override
public String toString() {
if( getResolution() == 0 ) {
return "";
}
final String NEWLINE = System.lineSeparator();
StringBuilder sb = new StringBuilder();
sb.append( " " );
for( int x = 0; x < getLength(); x++ ) {
sb.append( x );
}
sb.append( NEWLINE );
for( int y = 0; y < getHeight(); y++ ) {
sb.append( y );
for( int x = 0; x < getLength(); x++ ) {
sb.append( getPixel( x, y ) );
}
sb.append( NEWLINE );
}
return sb.toString();
}
}