2011-07-25 51 views
1

我有一个应用程序将鱼眼失真放在位图上。我已经给出了帮助,以便同时循环位图,为每个手机处理器的核心分配一个线程。这应该会使图像处理运行得更快。我得到一个NPE,我不认为PartialProcessing.call()方法返回partialResult。有没有人有任何想法?谢谢并发图像处理类中的NPE

public class MultiProcessorFilter { 



    private static final String TAG = "mpf"; 




    public Bitmap barrel (Bitmap input, float k){ 


      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; 

      ExecutorService threadPool = Executors.newFixedThreadPool(2); 

      FutureTask<PartialResult> task1 = (FutureTask<PartialResult>) threadPool.submit(new PartialProcessing(0, jMid - 1, input, k, iMid, iMax)); 
      FutureTask<PartialResult> task2 = (FutureTask<PartialResult>) threadPool.submit(new PartialProcessing(jMid, jMax - 1,input, k, iMid, iMax)); 
      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); 
      PartialResult result2 = task2.get(); // blocks until the thread returns the result 
      result2.fill(arr); 

      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
      Bitmap dst2 = Bitmap.createBitmap(arr,input.getWidth(),input.getHeight(),input.getConfig()); 
     return dst2; 


     } 




    public class PartialResult { 
      int startP; 
      int endP; 
      int[] storedValues; 

      public PartialResult(int startp, int endp){ 

       this.startP = startp; 
       this.endP = endp; 

      } 

      public void addValue(int p, int result) { 
       storedValues[p] = result; 
      } 

      public void fill(int[] arr) { 
       for (int p = startP; p < endP; p++) 
       arr[p] = storedValues[p]; 
       } 
      } 




    public class PartialProcessing implements Callable<PartialResult> { 
     int startJ; 
     int endJ; 

     // ... other members needed for the computation such as 
     private int[] scalar; 
     private float xscale; 
     private float yscale; 
     private float xshift; 
     private float yshift; 
     private float thresh = 1; 
     private int [] s1; 
     private int [] s2; 
     private int [] s3; 
     private int [] s4; 
     private int [] s; 
     private Bitmap input; 
     private float k; 
     private int startI; 
     private int endI; 


     public PartialProcessing(int startj, int endj, Bitmap input, float k, int starti, int endi) { 

      this.startJ = startj; 
      this.endJ = endj; 
      this.input = input; 
      this.k = k; 
      this.startI = starti; 
      this.endI = endi; 

     } 

     int [] getARGB(Bitmap buf,int x, int y){ 

      int rgb = buf.getPixel(y, x); // Returns by default ARGB. 
      // int [] scalar = new int[4]; 
      // scalar[0] = (rgb >>> 24) & 0xFF; 
      scalar[1] = (rgb >>> 16) & 0xFF; 
      scalar[2] = (rgb >>> 8) & 0xFF; 
      scalar[3] = (rgb >>> 0) & 0xFF; 
      return scalar; 

     } 

     //... add other methods needed for the computation that where in class Filters 

     float getRadialX(float x,float y,float cx,float cy,float k){ 

      x = (x*xscale+xshift); 
      y = (y*yscale+yshift); 
      float res = x+((x-cx)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy))); 
      return res; 
      } 

      float getRadialY(float x,float y,float cx,float cy,float k){ 

      x = (x*xscale+xshift); 
      y = (y*yscale+yshift); 
      float res = y+((y-cy)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy))); 
      return res; 
      } 



      float calc_shift(float x1,float x2,float cx,float k){ 

      float x3 = (float)(x1+(x2-x1)*0.5); 
      float res1 = x1+((x1-cx)*k*((x1-cx)*(x1-cx))); 
      float res3 = x3+((x3-cx)*k*((x3-cx)*(x3-cx))); 

      if(res1>-thresh && res1 < thresh) 
       return x1; 
      if(res3<0){ 
       return calc_shift(x3,x2,cx,k); 
      } 
      else{ 
       return calc_shift(x1,x3,cx,k); 
      } 
      } 


      void sampleImage(Bitmap arr, float idx0, float idx1) 
      { 

      // s = new int [4]; 
      if(idx0<0 || idx1<0 || idx0>(arr.getHeight()-1) || idx1>(arr.getWidth()-1)){ 
       s[0]=0; 
       s[1]=0; 
       s[2]=0; 
       s[3]=0; 
       return; 
      } 

      float idx0_fl=(float) Math.floor(idx0); 
      float idx0_cl=(float) Math.ceil(idx0); 
      float idx1_fl=(float) Math.floor(idx1); 
      float idx1_cl=(float) Math.ceil(idx1); 



      s1 = getARGB(arr,(int)idx0_fl,(int)idx1_fl); 
      s2 = getARGB(arr,(int)idx0_fl,(int)idx1_cl); 
      s3 = getARGB(arr,(int)idx0_cl,(int)idx1_cl); 
      s4 = getARGB(arr,(int)idx0_cl,(int)idx1_fl); 

      float x = idx0 - idx0_fl; 
      float y = idx1 - idx1_fl; 

      // s[0]= (int) (s1[0]*(1-x)*(1-y) + s2[0]*(1-x)*y + s3[0]*x*y + s4[0]*x*(1-y)); 
      s[1]= (int) (s1[1]*(1-x)*(1-y) + s2[1]*(1-x)*y + s3[1]*x*y + s4[1]*x*(1-y)); 
      s[2]= (int) (s1[2]*(1-x)*(1-y) + s2[2]*(1-x)*y + s3[2]*x*y + s4[2]*x*(1-y)); 
      s[3]= (int) (s1[3]*(1-x)*(1-y) + s2[3]*(1-x)*y + s3[3]*x*y + s4[3]*x*(1-y)); 


      } 


     // this will be called on some new thread 
     @Override public PartialResult call() { 
      PartialResult partialResult = new PartialResult(startJ, endJ); 

      float centerX=input.getWidth()/2; //center of distortion 
      float centerY=input.getHeight()/2; 



      int width = input.getWidth(); //image bounds 
      int height = input.getHeight(); 



       xshift = calc_shift(0,centerX-1,centerX,k); 

       float newcenterX = width-centerX; 
       float xshift_2 = calc_shift(0,newcenterX-1,newcenterX,k); 

       yshift = calc_shift(0,centerY-1,centerY,k); 

       float newcenterY = height-centerY; 
       float yshift_2 = calc_shift(0,newcenterY-1,newcenterY,k); 

       xscale = (width-xshift-xshift_2)/width; 

       yscale = (height-yshift-yshift_2)/height; 


      int p = startI; // not 0! at the start since we don't start at j = 0 
      int origPixel = 0; 
      int color = 0; 
      for (int j = startJ; j < endJ; j++){ 
       for (int i = startI; i < endI; i++, p++){ 
        //... copy the rest of the code 


        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); 

      }else{ 

       //arr[p]=origPixel; 
       partialResult.addValue(p, origPixel); 



      } 

       } 






        // partialResult.addValue(p, color); 
     } 
      return partialResult; 
    } 


} 

}//end of MultiProcesorFilter 

07-25 18:29:29.263: WARN/System.err(2289): java.util.concurrent.ExecutionException: java.lang.NullPointerException 
07-25 18:29:29.263: WARN/System.err(2289):  at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:223) 
07-25 18:29:29.263: WARN/System.err(2289):  at java.util.concurrent.FutureTask.get(FutureTask.java:82) 
07-25 18:29:29.268: WARN/System.err(2289):  at com.tecmark.MultiProcessorFilter.barrel(MultiProcessorFilter.java:39) 
07-25 18:29:29.268: WARN/System.err(2289):  at com.tecmark.TouchView$2.run(TouchView.java:147) 
07-25 18:29:29.268: WARN/System.err(2289):  at java.lang.Thread.run(Thread.java:1096) 
07-25 18:29:29.268: WARN/System.err(2289): Caused by: java.lang.NullPointerException 
07-25 18:29:29.268: WARN/System.err(2289):  at com.tecmark.MultiProcessorFilter$PartialProcessing.sampleImage(MultiProcessorFilter.java:170) 
07-25 18:29:29.273: WARN/System.err(2289):  at com.tecmark.MultiProcessorFilter$PartialProcessing.call(MultiProcessorFilter.java:245) 
07-25 18:29:29.273: WARN/System.err(2289):  at com.tecmark.MultiProcessorFilter$PartialProcessing.call(MultiProcessorFilter.java:1) 
07-25 18:29:29.273: WARN/System.err(2289):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
07-25 18:29:29.273: WARN/System.err(2289):  at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
07-25 18:29:29.278: WARN/System.err(2289):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068) 
07-25 18:29:29.278: WARN/System.err(2289):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561) 
07-25 18:29:29.278: WARN/System.err(2289):  ... 1 more 

[更新]

07-25 22:41:41.121: WARN/System.err(2212): Caused by: java.lang.NullPointerException 
07-25 22:41:41.126: WARN/System.err(2212):  at com.tecmark.MultiProcessorFilter$PartialResult.addValue(MultiProcessorFilter.java:70) 
07-25 22:41:41.126: WARN/System.err(2212):  at com.tecmark.MultiProcessorFilter$PartialProcessing.call(MultiProcessorFilter.java:262) 
07-25 22:41:41.126: WARN/System.err(2212):  at com.tecmark.MultiProcessorFilter$PartialProcessing.call(MultiProcessorFilter.java:1) 
07-25 22:41:41.126: WARN/System.err(2212):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
07-25 22:41:41.131: WARN/System.err(2212):  at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
07-25 22:41:41.131: WARN/System.err(2212):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068) 
07-25 22:41:41.131: WARN/System.err(2212):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561) 
07-25 22:41:41.131: WARN/System.err(2212):  ... 1 more 
+0

位图'input'为空。 –

+0

@nikola despotoski您好我刚刚登录了以下内容。 Log.e(TAG,“*********** bitmap input =”+ input.toString());并注销以下内容。 07-25 18:57:08.398:错误/ mpf(2743):***********位图输入= [email protected]。这是否意味着一个位图被传入。我得到一个黑色的空位图,其中的失真应该是。 – turtleboy

+1

在通过之前检查它是否为空 if(input == null)Log.i(“MY BITMAP IS”,“NULL”);你会看到 –

回答

1
sampleImage方法

// s = new int [4]; 

初始化数组小号被注释掉了,我没有注意到它被初始化其他地方

如果小号确实没有初始化,然后

s[0]=0; // just curious isn't this line 170 in MultiProcessorFilter.java? 

会抛出NPE

+0

嗨,是的,你是对的,我没有复制旧类的无拨号代码。现在在部分处理构造函数中这样做,所以所有变量现在都是初始化的,但仍然不起作用 – turtleboy

+0

您是否仍然在使用MultiProcessorFilter.java:170_上的java.lang.NullPointerException? – gnat

+0

这是现在注销的内容。包含相同行号的 – turtleboy