Reputation: 157
I've created an application that takes an image captured by the Android device, displays this image in the ImageView. The user can then press a button to either blur or deblur the image. When I run the application on my Android device I can take an image with the camera and display this without any problems. A problem occurs when I press the blur button, which runs some code to blur the image. The application becomes frozen and I get an OutOfMemoryException for a line of my code that creates a new array and stores this in another array in a nested for loop.
This is the code for the nested for loop:
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int xTranslated = (x + width / 2) % width;
int yTranslated = (y + height / 2) % height;
double real = temp[2 * (xTranslated + yTranslated * width)];
double imaginary = temp[2 * (xTranslated + yTranslated * width) + 1];
degradation[2 * (x + y * width)] = real;
degradation[2 * (x + y * width) + 1] = imaginary;
Complex c = new Complex(real, imaginary);
complex[y * width + x] = c;
}
}
This nested for loop deals with data extracted from the input image, which is stored as a Bitmap.
Here is the full method that applies the motion blur:
public Complex[] motionBlur(double[] degradation, int width, int height, double alpha, double gamma, double sigma) {
Complex[] complex = new Complex[width * height];
double[] temp = new double[2 * width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
double teta = Math.PI * ( (((x - width/2) % width) * gamma) + ((((y - height/2) % height) * sigma) ));
Sinc sinc = new Sinc();
double real = (Math.cos(teta) * sinc.value(teta)) * alpha;
double imaginary = (Math.sin(teta) * sinc.value(teta)) * alpha;
Complex cConj = new Complex(real, imaginary).conjugate();
temp[2 * (x + y * width)] = cConj.getReal();
temp[2 * (x + y * width) + 1] = cConj.getImaginary();
}
}
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int xTranslated = (x + width / 2) % width;
int yTranslated = (y + height / 2) % height;
double real = temp[2 * (xTranslated + yTranslated * width)];
double imaginary = temp[2 * (xTranslated + yTranslated * width) + 1];
degradation[2 * (x + y * width)] = real;
degradation[2 * (x + y * width) + 1] = imaginary;
Complex c = new Complex(real, imaginary);
complex[y * width + x] = c;
}
}
return complex;
}
Here is a link to what is being output by the logcat when I try to run the application: http://pastebin.com/ysbN9A3s
MainActivity.java:373 corresponds to the line,
Complex c = new Complex(real, imaginary);
Upvotes: 2
Views: 168
Reputation: 20130
Here is nice talk about android crashes.
Pierre-Yves talks about OOM (OutOfMemory error) at the time 11:39. So the problem in OOM is not place where OOM happens. You should profile your app to find the place where most memory is consumed. I should admit that OOM is one of the hardest error to resolve.
Good luck!
Upvotes: 3