Reputation: 3666
If I make a picture with mine samsung galaxy s2, the picture is 3264 x 2448 px. I want to use a color range check on that, but it doesn't work.
However, if I make the picture smaller for example, 2500 x 2500 (so less pixels), then it does work. But I want the use the picture size of the galaxy s2 (3264 x 2448). I think it is a memory issue? I don't exactly know anymore what the limit is. But is their another way to "bypass" this issue?
This is a piece of code, how I do it now:
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.four_colors);
int width = bmp.getWidth();
int height = bmp.getHeight();
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
int index = y * width + x;
int R = (pixels[index] >> 16) & 0xff; //bitwise shifting
int G = (pixels[index] >> 8) & 0xff;
int B = pixels[index] & 0xff;
total++;
if ((G > R)&&(G > B)){
counter++;
}
}
}
It crashes because the picture is to big, smaller pics work. So is their something to "bypass" this issue? instead of using smaller images :)
I tried some other things, without succes, I try to explain what I tried.
I tried to "cut" the image in two, and then scan it separate (didn't work).
and I tried to only scan the half of it (1632 x 1224) then rotate the image (180 degrees) and scan it again, but also this didn't work out.
Upvotes: 1
Views: 2256
Reputation: 17077
When playing around with huge images you really should be using the BitmapRegionDecoder to process it in chunks.
Edit - now with a simple example:
try {
// Processes file in res/raw/huge.jpg or png
BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(getResources().openRawResource(R.raw.huge), false);
try {
final int width = decoder.getWidth();
final int height = decoder.getHeight();
// Divide the bitmap into 1024x768 sized chunks and process it.
int wSteps = (int) Math.ceil(width / 1024.0);
int hSteps = (int) Math.ceil(height / 768.0);
Rect rect = new Rect();
long total = 0L, counter = 0L;
for (int h = 0; h < hSteps; h++) {
for (int w = 0; w < wSteps; w++) {
int w2 = Math.min(width, (w + 1) * 1024);
int h2 = Math.min(height, (h + 1) * 768);
rect.set(w * 1024, h * 768, w2, h2);
Bitmap bitmap = decoder.decodeRegion(rect, null);
try {
int bWidth = bitmap.getWidth();
int bHeight = bitmap.getHeight();
int[] pixels = new int[bWidth * bHeight];
bitmap.getPixels(pixels, 0, bWidth, 0, 0, bWidth, bHeight);
for (int y = 0; y < bHeight; y++){
for (int x = 0; x < bWidth; x++){
int index = y * bWidth + x;
int R = (pixels[index] >> 16) & 0xff; //bitwise shifting
int G = (pixels[index] >> 8) & 0xff;
int B = pixels[index] & 0xff;
total++;
if ((G > R)&&(G > B)){
counter++;
}
}
}
} finally {
bitmap.recycle();
}
}
}
} finally {
decoder.recycle();
}
Upvotes: 5
Reputation: 36806
You can limit the amount of pixel data of the image that you are loading at once by using some of the parameters of the getPixels method. I did something very similar, and I would read them one row at a time, for example.
for(int y = 0; y < height; y++)
{
bitmap.getPixels(pixels, 0, width, 0, y, width, 1);
Upvotes: 1