99import javax .imageio .ImageIO ;
1010
1111public class FragTransparent extends Frag {
12- private int [][] monoXY_Map = null ; // much faster than using array of objects
12+ private int [][] XY_Map = null ; // much faster than using array of objects
1313
1414 FragTransparent (String path ) throws Exception {
1515 super ();
1616 File f = new File (path );
1717 image = ImageIO .read (f );
1818 rgbData = loadFromFile (image );
19- prepareMonoPixelMap ();
19+ preparePixelMap ();
2020 }
2121
22- private void prepareMonoPixelMap () {
22+ private void preparePixelMap () {
2323 int [] row_cache = null ;
2424 final int line = rgbData .length ;
2525 final int column = rgbData [0 ].length ;
@@ -34,11 +34,11 @@ private void prepareMonoPixelMap() {
3434 al .add (new Point (x , y ));
3535 }
3636
37- monoXY_Map = new int [2 ][al .size ()];
37+ XY_Map = new int [2 ][al .size ()];
3838 for (int i = 0 ; i < al .size (); i ++) {
3939 Point p = al .get (i );
40- monoXY_Map [0 ][i ] = (int ) p .getX ();
41- monoXY_Map [1 ][i ] = (int ) p .getY ();
40+ XY_Map [0 ][i ] = (int ) p .getX ();
41+ XY_Map [1 ][i ] = (int ) p .getY ();
4242 }
4343 }
4444
@@ -74,18 +74,48 @@ public void makeFile(String name) throws Exception {
7474 }
7575
7676 public Position findSimilarIn (Frag b , double rate , int x_start , int y_start , int x_stop , int y_stop ) {
77- return null ;
77+ // precalculate all frequently used data
78+ final int [][] small = this .rgbData ;
79+ final int [][] big = b .rgbData ;
80+ final long maxDiff = 3 * 255 * XY_Map [0 ].length ;
81+ // similarity rate 95% is equal to 5% difference rate.
82+ // if differences reached this number, then no need to check the rest, continue
83+ // to next position
84+ final long maxBreakDiff = (long ) ((1 - rate ) * maxDiff );
85+ long leastDifference = Long .MAX_VALUE ;
86+ Position bestResultMatrixPosition = null ;
87+
88+ final int [] rowY = XY_Map [1 ];
89+ final int [] rowX = XY_Map [0 ];
90+ final int pixelMapLen = rowX .length ;
91+ for (int y = y_start ; y < y_stop ; y ++) {
92+ __columnscan : for (int x = x_start ; x < x_stop ; x ++) {
93+ long diff = 0 ;// sum difference values
94+ for (int yy = 0 ; yy < pixelMapLen ; yy ++)
95+ diff += pixelDiffARGB (big [y + rowY [yy ]][x + rowX [yy ]], small [rowY [yy ]][rowX [yy ]]);
96+ if (diff > maxBreakDiff )
97+ continue __columnscan ; // no match
98+
99+ if (diff == 0 )
100+ return new Position (x , y ); // full match
101+ else if (diff < leastDifference ) { // found better match
102+ leastDifference = diff ;
103+ bestResultMatrixPosition = new Position (x , y );
104+ }
105+ }
106+ }
107+ return bestResultMatrixPosition ;
78108 }
79109
80110 public Position findIn (Frag b , int x_start , int y_start , int x_stop , int y_stop ) {
81111 final int [][] big = b .rgbData ;
82112 final int [][] small = rgbData ;
83- final int [] monoY = monoXY_Map [1 ];
84- final int [] monoX = monoXY_Map [0 ];
85- final int jumpX = monoX [0 ];
86- final int jumpY = monoY [0 ];
113+ final int [] rowY = XY_Map [1 ];
114+ final int [] rowX = XY_Map [0 ];
115+ final int jumpX = rowX [0 ];
116+ final int jumpY = rowY [0 ];
87117 final int first_pixel = small [jumpY ][jumpX ];
88- final int pixelMapLen = monoX .length ;
118+ final int pixelMapLen = rowX .length ;
89119
90120 int [] row_cache_big = null ;
91121 for (int y = y_start ; y < y_stop ; y ++) {
@@ -96,7 +126,7 @@ public Position findIn(Frag b, int x_start, int y_start, int x_stop, int y_stop)
96126 // There is a match for the first element in small
97127 // Check if all the elements in small matches those in big
98128 for (int yy = 0 ; yy < pixelMapLen ; yy ++)
99- if (big [y + monoY [yy ]][x + monoX [yy ]] != small [monoY [yy ]][monoX [yy ]])
129+ if (big [y + rowY [yy ]][x + rowX [yy ]] != small [rowY [yy ]][rowX [yy ]])
100130 continue __columnscan ;
101131 return new Position (x , y );
102132 }
@@ -107,13 +137,13 @@ public Position findIn(Frag b, int x_start, int y_start, int x_stop, int y_stop)
107137 public Position [] findAllIn (Frag b , int x_start , int y_start , int x_stop , int y_stop ) {
108138 final int [][] big = b .rgbData ;
109139 final int [][] small = rgbData ;
110- final int [] monoY = monoXY_Map [1 ];
111- final int [] monoX = monoXY_Map [0 ];
112- final int jumpX = monoX [0 ];
113- final int jumpY = monoY [0 ];
140+ final int [] rowY = XY_Map [1 ];
141+ final int [] rowX = XY_Map [0 ];
142+ final int jumpX = rowX [0 ];
143+ final int jumpY = rowY [0 ];
114144 final int first_pixel = small [jumpY ][jumpX ];
115145 ;
116- final int pixelMapLen = monoX .length ;
146+ final int pixelMapLen = rowX .length ;
117147
118148 ArrayList <Position > result = null ;
119149 Position matrix_position_list [] = null ;
@@ -126,7 +156,7 @@ public Position[] findAllIn(Frag b, int x_start, int y_start, int x_stop, int y_
126156 // There is a match for the first element in small
127157 // Check if all the elements in small matches those in big
128158 for (int yy = 0 ; yy < pixelMapLen ; yy ++)
129- if (big [y + monoY [yy ]][x + monoX [yy ]] != small [monoY [yy ]][monoX [yy ]])
159+ if (big [y + rowY [yy ]][x + rowX [yy ]] != small [rowY [yy ]][rowX [yy ]])
130160 continue __columnscan ;
131161 // If arrived here, then the small matches a region of big
132162 if (result == null )
0 commit comments