2017-02-28 1 views
1

다음은 RGB 색상을 얻고 비트 맵 (다른 비트 맵)의 색상이 녹색 인 경우 temp (비트 맵)의 색상을 변경하는 방법입니다. 그러나 성능은 상당히 좋지 않으며 시간은 약 20 초 이상 사용됩니다. 그것을 개선 할 수있는 방법이 있습니까? 고맙습니다.안드로이드에서 RGB를 더 빨리 가져 오기

//get the green color of each pixel 
    color = new int[bitmap.getWidth()][bitmap.getHeight()]; 
    for (int x = 0; x < bitmap.getWidth(); x++) { 
     for (int y = 0; y < bitmap.getHeight(); y++) { 
      color[x][y] = temp.getPixel(x, y); 
      if (bitmap.getPixel(x, y) == Color.GREEN) { 
       color[x][y] = temp.getPixel(x, y); 
       float[] hsv = new float[3]; 
       Color.RGBToHSV(Color.red(color[x][y]), Color.green(color[x][y]), Color.blue(color[x][y]), hsv); 
       hsv[0] = 360; 
       color[x][y] = Color.HSVToColor(hsv); 
      } 
      temp.setPixel(x, y, color[x][y]); 
     } 
    } 

imageView.setImageBitmap(temp); 

업데이트 :

intArray = new int[bitmap.getWidth()*bitmap.getHeight()]; 
        bitmap.getPixels(intArray,0,bitmap.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight()); 

    int[] tempArray = new int[bitmap.getWidth()*bitmap.getHeight()]; 
     temp.getPixels(tempArray,0,temp.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight()); 

    //get the color of each pixel 
    color = new int[bitmap.getWidth()][bitmap.getHeight()]; 
    for (int x = 0; x < bitmap.getWidth(); x++) { 
     for (int y = 0; y < bitmap.getHeight(); y++) { 
      if (intArray[x + y * bitmap.getWidth()] == Color.BLUE) { 
       float[] hsv = new float[3]; 
       Color.RGBToHSV(Color.red(tempArray[x + y * bitmap.getWidth()]), Color.green(tempArray[x + y * bitmap.getWidth()]), Color.blue(tempArray[x + y * bitmap.getWidth()]), hsv); 
       hsv[0] = 360; 
       tempArray[x + y * bitmap.getWidth()] = Color.HSVToColor(hsv); 

      } 
     } 
    } 

    temp.setPixels(tempArray,0,temp.getWidth(),0,0,temp.getWidth(),temp.getHeight()); 

    imageView.setImageBitmap(temp); 

답변

1

이것을 더 빨리 만드는 방법은 여러 가지가있다. 의 가장 쉬운 것들부터 시작하자 :


float[] hsv = new float[3];

new 속도가 느린 친절한 캐시하지 (그리고 나중에 해제 할 필요가 힙에 메모리를 할당하여 (이것은 자동으로 할 수있는 언어에 따라)). 대신에 로컬 플로트 [3]을 (다시) 사용할 수 있습니다.


color[x][y] = temp.getPixel(x, y); 
    if (bitmap.getPixel(x, y) == Color.GREEN) { 
     color[x][y] = temp.getPixel(x, y); 

두 번째 temp.getPixel() (느린 될 수있는) 여기서 할 필요가 없습니다. 데이터는 이미 color[x][y]입니다.


color[x][y] = temp.getPixel(x, y); 
    if (bitmap.getPixel(x, y) == Color.GREEN) { 
     // ... 
    } 
    temp.setPixel(x, y, color[x][y]); 

변경되지 않은 경우 픽셀을 설정할 필요가 없습니다. 따라서 if 블록 안으로 temp.setPixel을 이동할 수 있습니다. 그리고


color = new int[bitmap.getWidth()][bitmap.getHeight()]; 

먼저 실제로 color[x][y] = temp.getPixel(x, y); 또한 if 블록 안에 갈 수있는 (또는 같은이 if 블록 내부에 이미 있기 때문에 그냥 바깥 하나를 제거), 당신은 아마 여기 unsigned int를 사용하기를 원하지만 실제로 이 세 번째 배열은 필요하지 않습니다. 대신 로컬 unsigned int color 변수를 사용할 수 있습니다.


for (int x = 0; x < bitmap.getWidth(); x++) { 
    for (int y = 0; y < bitmap.getHeight(); y++) { 

은 언어에 따라 (this 참조) 친화적 인 더 캐시로 루프의 순서를 반대로 할 수 있습니다. 가장 쉬운 방법은 두 주문 모두에 대해 빠른 테스트를하는 것입니다.


getPixel()setPixel()는 (다시 언어에 따라) 속도가 느려질 수 있습니다. 2 차원 배열처럼 픽셀 데이터를 직접 작업하는 것이 좋습니다. 대부분의 언어는 원시 픽셀 데이터에 대한 포인터 또는 액세스를 얻기위한 함수를 제공합니다.

+0

답장을 보내 주셔서 감사합니다. 2 차원 배열처럼 픽셀 데이터를 직접 작업하는 것이 좋습니다. <- 나는 이것에 상당히 흥미가있다. 좀 더 설명해 주시겠습니까? – ng2b30

+0

@ ng2b30'getPixel()'과'setPixel()'을 사용하는 대신 픽셀 배열에 직접 접근 할 수 있는데, 이렇게하면 훨씬 더 빠릅니다 :'byte [] pixels = ((DataBufferByte) bufferedImage.getRaster(). getDataBuffer()) .getData();'- see http://stackoverflow.com/questions/6524196/java-get-pixel-array-from-image –

+0

질문이 있습니다. 갤러리에서 PNG 이미지를 불러 와서 bufferedImage로 바꾸려면 어떻게해야하나요? 감사. – ng2b30

0

나는 내가 무엇을 할 것이라고하는 것은 각 픽셀의 크기를 결정하는 것 같다. 대부분 32 비트 ARGB입니다. 그래서 당신은 WxH longs의 배열을 가지고 있습니다. 해당 배열을 반복하고 값이 G = 255이면 무엇이든간에 값을 바꿉니다. 나는 또한 알파 채널을 무시할 것이다.

+0

몇 가지 예를 들어 주시겠습니까? 고맙습니다. – ng2b30

관련 문제