i've an app that loops through a bitmap and places a distortion on it. i've re-written the image-processing part to run in parallel. the distorted bitmap only seems to have the top row of pixels set, the rest of the bitmap is black, indicating that the array from which the new bitmap was made is nearly empty. i think i have a looping problem. i've used executorservice to manage my threads and created 2 threads. thread one should loop from 0 to bitmap.height/2 and thread 2 should loop from bitmap.height/2 to bitmap.height. can anyone help me sort the looping problem. I've not included alot of the code that processes the bitmap but will post it if it helps thanks.
.
public class MultiProcessorFilter {
private static final String TAG = "mpf";
public Bitmap barrel (Bitmap input, float k){
if(input!=null){
Log.e(TAG, "*********** bitmap input = "+input.toString());
}
int []arr = new int[input.getWidth()*input.getHeight()];
// replace the j, i for loops:
int jMax = input.getHeight();
int jMid = jMax / 2;
int iMax = input.getWidth();
int iMid = iMax / 2;
int nrOfProcessors = Runtime.getRuntime().availableProcessors();
Log.e(TAG, "*********** NUM OF PROCESSORS = " + nrOfProcessors);
ExecutorService threadPool = Executors.newFixedThreadPool(2);
FutureTask<PartialResult> task1 = (FutureTask<PartialResult>) threadPool.submit(new PartialProcessing(0, jMid - 1, input, k));
FutureTask<PartialResult> task2 = (FutureTask<PartialResult>) threadPool.submit(new PartialProcessing(jMid, jMax - 1,input, k));
Log.e(TAG, "*********** about to call task1.get()");
try{
PartialResult result1 = task1.get();// blocks until the thread returns the result
Log.e(TAG, "*********** just called task1.get()");
result1.fill(arr);
Log.e(TAG, "*********** result1 arr length = " + arr.length);
Log.e(TAG, "*********** about to call task2.get()");
PartialResult result2 = task2.get(); // blocks until the thread returns the result
Log.e(TAG, "*********** just called task2.get()");
result2.fill(arr);
Log.e(TAG, "*********** result2 arr length = " + arr.length);
}catch(Exception e){
e.printStackTrace();
}
Bitmap dst2 = Bitmap.createBitmap(arr,input.getWidth(),input.getHeight(),input.getConfig());
if(dst2!=null)
Log.e(TAG, "*********** dst2 is not null" );
return dst2;
}
public class PartialResult {
int startP;
int endP;
int[] storedValues;
public PartialResult(int startp, int endp, Bitmap input){
this.startP = startp;
this.endP = endp;
this.storedValues = new int[input.getWidth()*input.getHeight()];
Log.e(TAG, "*********** input w = "+input.getWidth());
Log.e(TAG, "*********** input dim h = "+input.getHeight());
}
public void addValue(int p, int result) {
storedValues[p] = result;
// Log.e(TAG, "*********** p = " + p + "result = " + result);
}
public void fill(int[] arr) {
int x = 0;
// Log.e(TAG, "*********** startP = "+startP + " endP = " + endP);
for (int p = startP; p < endP; p++, x++)
arr[p] = storedValues[p];
Log.e(TAG, "*********** arr = " + arr[x]);
}
}
public class PartialProcessing implements Callable<PartialResult> {
int startJ;
int endJ;
// ... other members needed for the computation
public PartialProcessing(int startj, int endj, Bitmap input, float k) {
this.startJ = startj;
this.endJ = endj;
this.input = input;
this.k = k;
}
int [] getARGB(Bitmap buf,int x, int y){
method for processing
}
//... add other methods needed for the computation that where in class Filters
float getRadialX(float x,float y,float cx,float cy,float k){
method for processing
}
float getRadialY(float x,float y,float cx,float cy,float k){
method for processing
}
float calc_shift(float x1,float x2,float cx,float k){
method for processing
}
void sampleImage(Bitmap arr, float idx0, float idx1)
{
method for processing
}
// this will be called on some new thread
@Override public PartialResult call() {
PartialResult partialResult = new PartialResult(startJ, endJ,input);
int p = startJ; // not 0! at the start since we don't start at j = 0
int origPixel = 0;
int color = 0;
int i;
for (int j = startJ; j < endJ; j++){
// Log.e(TAG, "*********** j = "+j );
for ( i = 0; i < width; i++, p++){
//... copy the rest of the code
// Log.e(TAG, "*********** i = " + i);
origPixel = input.getPixel(i,j);
float x = getRadialX((float)j,(float)i,centerX,centerY,k);
float y = getRadialY((float)j,(float)i,centerX,centerY,k);
sampleImage(input,x,y);
color = ((s[1]&0x0ff)<<16)|((s[2]&0x0ff)<<8)|(s[3]&0x0ff);
if(((i-centerX)*(i-centerX) + (j-centerY)*(j-centerY)) <= 5500){
//arr[p]=color;
partialResult.addValue(p, color);
// Log.e(TAG, "*********** color = " + color);
}else{
//arr[p]=origPixel;
partialResult.addValue(p, origPixel);
}
}
// partialResult.addValue(p, color);
}
return partialResult;
}
}
}//end of MultiProcesorFilter
.
[update 1]
.
07-31 13:50:29.548: ERROR/mpf(3354): *********** bitmap input = android.graphics.Bitmap@43cd2780
07-31 13:50:29.553: ERROR/mpf(3354): *********** NUM OF PROCESSORS = 1
07-31 13:50:29.553: ERROR/mpf(3354): *********** about to call task1.call()
07-31 13:50:29.558: ERROR/mpf(3354): *********** input w = 150
07-31 13:50:29.563: ERROR/mpf(3354): *********** input h = 150
07-31 13:50:30.348: ERROR/mpf(3354): *********** just called part1.call()
07-31 13:50:30.348: ERROR/mpf(3354): *********** result1 arr length = 22500
07-31 13:50:30.348: ERROR/mpf(3354): *********** about to call part2.()
07-31 13:50:30.353: ERROR/mpf(3354): *********** input w = 150
07-31 13:50:30.353: ERROR/mpf(3354): *********** input h = 150
07-31 13:50:31.143: ERROR/mpf(3354): *********** just called part2.call()
07-31 13:50:31.143: ERROR/mpf(3354): *********** result2 arr length = 22500
07-31 13:50:31.173: DEBUG/WifiService(1911): ACTION_BATTERY_CHANGED pluggedType: 2
07-31 13:50:31.183: ERROR/mpf(3354): *********** dst2 is not null
07-31 13:50:31.188: ERROR/mpf(3354): *********** bitmap input = android.graphics.Bitmap@43ccb060
07-31 13:50:31.253: DEBUG/dalvikvm(3354): GC freed 652 objects / 124416 bytes in 65ms
07-31 13:50:31.258: ERROR/mpf(3354): *********** NUM OF PROCESSORS = 1
07-31 13:50:31.258: ERROR/mpf(3354): ***********开发者_JAVA百科 about to call task1.call()
07-31 13:50:31.258: ERROR/mpf(3354): *********** input w = 150
07-31 13:50:31.258: ERROR/mpf(3354): *********** input h = 150
07-31 13:50:32.093: ERROR/mpf(3354): *********** just called part1.call()
07-31 13:50:32.093: ERROR/mpf(3354): *********** result1 arr length = 22500
07-31 13:50:32.093: ERROR/mpf(3354): *********** about to call part2.()
07-31 13:50:32.098: ERROR/mpf(3354): *********** input w = 150
07-31 13:50:32.098: ERROR/mpf(3354): *********** input h = 150
07-31 13:50:33.078: ERROR/mpf(3354): *********** just called part2.call()
07-31 13:50:33.078: ERROR/mpf(3354): *********** result2 arr length = 22500
07-31 13:50:33.083: ERROR/mpf(3354): *********** dst2 is not null
.
[update2]
public void fill(int[] arr) {
int x = 0;
Log.e(TAG, "*********** startP = "+startP + " endP = " + endP);
for (int p = startP; p < endP; p++, x++){
arr[p] = storedValues[p];
}
Log.e(TAG, "*********** arr size = "+arr.length);
Log.e(TAG, "*********** storedValues size = "+storedValues.length);
}
}
.
07-31 14:26:18.788: ERROR/mpf(6380): *********** just called task1.get()
07-31 14:26:18.788: ERROR/mpf(6380): *********** startP = 0 endP = 74
07-31 14:26:18.788: ERROR/mpf(6380): *********** arr size = 22500
07-31 14:26:18.788: ERROR/mpf(6380): *********** storedValues size = 22500
07-31 14:26:18.788: ERROR/mpf(6380): *********** result1 arr length = 22500
07-31 14:26:18.788: ERROR/mpf(6380): *********** about to call task2.get()
07-31 14:26:18.818: ERROR/mpf(6380): *********** just called task2.get()
07-31 14:26:18.818: ERROR/mpf(6380): *********** startP = 75 endP = 149
07-31 14:26:18.818: ERROR/mpf(6380): *********** arr size = 22500
07-31 14:26:18.818: ERROR/mpf(6380): *********** storedValues size = 22500
07-31 14:26:18.818: ERROR/mpf(6380): *********** result2 arr length = 22500
07-31 14:26:18.823: ERROR/mpf(6380): *********** dst2 is not null
07-31 14:26:18.823: ERROR/mpf(6380): *********** bitmap input = android.graphics.Bitmap@43ce62c0
.
[update3]
public void fill(int[] arr) {
Log.e(TAG, "*********** startP = "+startP + " endP = " + endP);
for (int p = startP; p < endP; p++){
for(int b=0;b<150;b++,x++)
arr[x] = storedValues[x];
}
Log.e(TAG, "*********** arr size = "+arr.length);
Log.e(TAG, "*********** storedValues size = "+storedValues.length);
Log.e(TAG, "*********** x = "+x);
}
}
Not yet a full answer, but too large for a comment.
I can't really test your program, but for debugging purposes please change this method:
public Bitmap barrel (Bitmap input, float k){
if(input!=null){
Log.e(TAG, "*********** bitmap input = "+input.toString());
}
int []arr = new int[input.getWidth()*input.getHeight()];
// replace the j, i for loops:
int jMax = input.getHeight();
int jMid = jMax / 2;
int iMax = input.getWidth();
int iMid = iMax / 2;
int nrOfProcessors = Runtime.getRuntime().availableProcessors();
Log.e(TAG, "*********** NUM OF PROCESSORS = " + nrOfProcessors);
PartialProcessing part1 = new PartialProcessing(0, jMid - 1, input, k);
PartialProcessing part2 = new PartialProcessing(jMid, jMax - 1,input, k);
Log.e(TAG, "*********** about to call task1.call()");
try{
PartialResult result1 = part1.call();// blocks until the thread returns the result
Log.e(TAG, "*********** just called part1.call()");
result1.fill(arr);
Log.e(TAG, "*********** result1 arr length = " + arr.length);
Log.e(TAG, "*********** about to call part2.()");
PartialResult result2 = part2.call(); // blocks until the thread returns the result
Log.e(TAG, "*********** just called part2.call()");
result2.fill(arr);
Log.e(TAG, "*********** result2 arr length = " + arr.length);
}catch(Exception e){
e.printStackTrace();
}
Bitmap dst2 = Bitmap.createBitmap(arr,input.getWidth(),input.getHeight(),input.getConfig());
if(dst2!=null)
Log.e(TAG, "*********** dst2 is not null" );
return dst2;
}
This would be a serial variant of your program. Run this, and check if it works.
- If it does, we have a problem with the concurrency.
- If it does not work, the problem is in your actual implementation, independent of the concurrency.
the nearly empty bitmap is still the result of the processing
Okay, so we know this is not concurrency-related. Let's look at the points where the pixels are set. One is here, in PartialResult:
public void fill(int[] arr) {
int x = 0;
// Log.e(TAG, "*********** startP = "+startP + " endP = " + endP);
for (int p = startP; p < endP; p++, x++)
arr[p] = storedValues[p];
Log.e(TAG, "*********** arr = " + arr[x]);
}
}
This sets the elements of arr
from startP
to endP
to some stored values. Now please have a look at the actual values of startP
and endP
in comparison to the sizes of storedValues
and arr
, and I suppose you'll get why there is only a first line of pixels.
After update 3:
It gets better. Now have a look where your x
starts in the fill
method (in the old one it was 0
, I'm not sure about the new one - it should be startP*150
), and where your p
starts in the call
method (it starts at startJ
- I think it should start at startJ * 150
, too).
精彩评论