Somebody somewhere is going to have to loop thru the pixels to find differences. Are you sure it's too time consuming? If you haven't tried it, I would not jump to conclusions about performance. You'll simply be comparing two arrays of ints in a tiny loop - that's about as fast as anything can be.
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
I'd use the PixelGrabber class to convert the images to simple int arrays, then compare those arrays. Each int is 1 pixel , and there's no need to decode the individual rgb values.
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
Yo. Loop thru the x/y coords iin a nested loop and record the first and last x and the first and last y where there is a difference. Those 4 numbers will define the smallest rectangle that contains the pixels that are different
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
line 8:
the index into the arrays is i + j* w
(the arrays ate in row order)
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
Dunno what you mean by "infinite values", but maybe you should get things working one at a time, starting with easy data.
What I would do is to create two small bitmap images (no compression artefacts) say 16 * 8 pixels with just a couple of known pixels different, and use these to test my compare routine.
When that's working 100% I'd move on to bigger images until I was at full size. From that I'd get a relationship between image size and execution time, and have a test bed for any perfomance tuning.
I wouldn't attempt to do any of the above in the context of the full working program.
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
Just get a 1024*1280 image and try it ! It's only a million integer compares - on a multi-Gig processor.
It's such a common mistake that it has its own name: "premature optimisation".
Confirm that it really is a problem, then let's discuss optimisations.
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
Just for fun I created two int arrays 1280*1024 and compared them in a simple nested loop.
The followin code executes in 20 milliSecs on my old laptop
final int w=1280, h=1024;
int[] array1 = new int[w*h];
int[] array2 = new int[w*h];
long start = new Date().getTime();
int mismatches = 0;
int index = 0;
for (int x = 0; x< w; x++) {
for (int y = 0; y< h; y++) {
if (array1[index] != array2[index]) mismatches++;
index ++;
}
}
System.out.println(new Date().getTime() - start);
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
You'll notice I replaced the i+j*w repeated calc with a simple index counter. That reduced my benchmark from 68 ms to 20. Suggest you try that.
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
I don't think multiple threads will help much unless you have a quad processor! You already have GUI and socket IO running (presumably) on different threads. I'm still surprised by your lomg timings - my 20 mSec was on a 1.66 GHz core 2 laptop.
Also, in your benchmark code you grab both sets of pixels - in the real case you can just grab the latest image and pass the previous one forwards.
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
Multiple rectanges: I hate the idea of trying to find a variable number of rectanges of variable size that minimise the total area that conatins all modified pixels. Sounds like a programming nightmare, and the overheads will probably exceed he gains.
But: how about dividing the image into fixed 8x8 pixel cells and finding the cells that have changed? That's like MPEG, and really fast & easy.
boolean[][] cellChanged = new boolean[w >> 3][h >> 3];
int index = 0;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
if (array1[index] != array2[index])
cellChanged[x >> 3][y >> 3] = true;
index++;
}
}
for (int y = 0; y < (h >> 3); y++) {
for (int x = 0; x < (w >> 3); x++) {
System.out.print(cellChanged[x][y] ? "1" : "0");
}
System.out.println("");
}
Now you've also got an easy starting place for transmitting only the cells that have changed, and each cell is small enough that you can just transmit it all.
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073