0

나는 비트 맵을 반복하며 왜곡을하는 앱을 가지고있다. 나는 병렬로 실행하기 위해 이미지 프로세싱 부분을 다시 썼다. 왜곡 된 비트 맵은 맨 위의 픽셀 행을 가진 것처럼 보이고 나머지 비트 맵은 검은 색이어서 새 비트 맵이 만들어진 배열이 거의 비어 있음을 나타냅니다. 나는 루핑 문제가 있다고 생각한다. executorservice를 사용하여 스레드를 관리하고 스레드 2 개를 생성했습니다. thread 하나는 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 = [email protected] 
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 = [email protected] 
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 

.

[갱신 2]

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 = [email protected] 

.

[업데이트 3]

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 개의'PartialProcessing' 호출을 차례로 사용하면이 기능이 작동합니까? –

+0

@paulo ebermann 안녕하세요, 무슨 뜻인지 확실하지 않습니다. 나는 2 개의 부분 처리 호출을 하나씩 호출하고 비트 맵의 ​​첫 번째 행만이 storedValues의 배열에 기록됩니다. storedValues는 PartialResult.fill()에서 궁극적 인 비트 맵이 파생되는 배열을 채우는 데 사용됩니다. – turtleboy

+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에서, 여기에이 일부 저장된 값 endP-startParr에서의 요소를 설정

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

.이제 storedValuesarr 크기와 비교하여 startPendP의 실제 값을 살펴 보시기 바랍니다. 그러면 첫 번째 픽셀 만 나타나는 이유를 알 수 있습니다.


갱신 3 후 :

이 더 좋아진다. 이제 귀하의 x이 방법으로 시작되는 모습을보십시오 (예전에는 0이었습니다. 새로운 것이 확실하지 않습니다 - startP*150이어야합니다), 그리고 어디에서 이 call 방법으로 시작하는지 startJ - 나는 startJ * 150에서 시작해야한다고 생각합니다.)

+0

ebermann. 코드를 실행하는 중 로깅을 포함하도록 게시물을 업데이트했습니다. – turtleboy

+0

거의 빈 비트 맵은 여전히 ​​처리 결과입니다. – turtleboy

+0

ebermann 업데이트 2를 게시했습니다 – turtleboy

관련 문제