我有一个应用程序循环通过位图并在其上放置一个失真。我重写了图像处理部分并行运行。失真的位图似乎只有顶行的像素集,其余的位图是黑色的,表明制作新位图的数组几乎是空的。我想我有一个循环问题。我使用executorservice来管理我的线程并创建了2个线程。线程一应该从0循环到bitmap.height / 2,线程2应该从bitmap.height / 2循环到bitmap.height。任何人都可以帮我解决循环问题。我没有包含很多处理位图的代码,但如果它有帮助,我会发布它。
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
[更新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): *********** 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);
}
}
答案 0 :(得分:2)
尚未完整答案,但评论太大了。
我无法真正测试您的程序,但出于调试目的,请更改此方法:
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;
}
这将是您程序的一个系列变体。运行它,检查它是否有效。
几乎空的位图仍然是处理的结果
好的,我们知道这不是与并发相关的。让我们看看像素设置的点。 一个在这里,在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]);
}
}
这会将arr
从startP
到endP
的元素设置为某些存储值。现在,请查看startP
和endP
的实际值与storedValues
和arr
的尺寸进行比较,我想您会明白为什么只有第一行像素。
更新3之后:
变得更好。现在看一下x
方法中fill
开始的位置(在原来的0
中,我不确定新的方法 - 它应该是startP*150
}},以及p
方法中call
开始的位置(从startJ
开始 - 我认为它应该从startJ * 150
开始。