2013-01-05 1 views
0

현재 BufferedImage을 음악으로 변환하는 프로그램을 작성 중입니다. BufferedImage의 폭과 높이를 얻으면 값이 정확합니다. 그러나, FOR 루프 내에서 픽셀을 얻으려고하는데, FOR 루프 값 (i++) 중 하나를 조작하고 있습니다. void 끝에서 값을 원래 상태 (i--)로 다시 설정합니다. 이 프로그램은 전체 이미지를 평가하고, 대신 나에게이 오류 제공하지 않습니다 고도 조작시 BufferedImage에서 픽셀 가져 오기

java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds! 

가 어떻게이 오류를 수정해야

를? 여기에 내 코드가있다 :

 try { 
      String fp = jTextField1.getText(); 
      File pict = new File(fp); 
      BufferedImage img = ImageIO.read(pict); 
      // int keybase = img.getRGB(1, 1); 
      // int red = (keybase & 0x00ff0000) >> 16; 
      // int green = (keybase & 0x0000ff00) >> 8; 
      // int blue = keybase & 0x000000ff; 
      int width = img.getWidth(); 
      int height = img.getHeight(); 
      String key = null; 
      int keybase = img.getRGB(1, 1); 
      int keyred = (keybase & 0x00ff0000) >> 16; 
      int keygreen = (keybase & 0x0000ff00) >> 8; 
      int keyblue = keybase & 0x000000ff; 
      int keyAvg = (keyred + keygreen + keyblue)/3; 
      if (keyAvg <= 10) { 
       key = "Cmaj"; 
      } 
      else if (keyAvg <=20 && keyAvg > 10) { 
       key = "Cmin"; 
      } 
      else if (keyAvg <=30 && keyAvg > 20) { 
       key = "C#maj"; 
      } 
      else if (keyAvg <=40 && keyAvg > 30) { 
       key = "C#min"; 
      } 
      else if (keyAvg <=50 && keyAvg > 40) { 
       key = "Dmaj"; 
      } 
      else if (keyAvg <=60 && keyAvg > 50) { 
       key = "Dmin"; 
      } 
      else if (keyAvg <=70 && keyAvg > 60) { 
       key = "D#maj"; 
      } 
      else if (keyAvg <=80 && keyAvg > 70) { 
       key = "D#min"; 
      } 
      else if (keyAvg <=90 && keyAvg > 80) { 
       key = "Emaj"; 
      } 
      else if (keyAvg <=100 && keyAvg > 90) { 
       key = "Emin"; 
      } 
      else if (keyAvg <=110 && keyAvg > 100) { 
       key = "Fmaj"; 
      } 
      else if (keyAvg <=120 && keyAvg > 110) { 
       key = "Fmin"; 
      } 
      else if (keyAvg <=130 && keyAvg > 120) { 
       key = "F#maj"; 
      } 
      else if (keyAvg <=140 && keyAvg > 130) { 
       key = "F#min"; 
      } 
      else if (keyAvg <=150 && keyAvg > 140) { 
       key = "Gmaj"; 
      } 
      else if (keyAvg <=160 && keyAvg > 150) { 
       key = "Gmin"; 
      } 
      else if (keyAvg <=170 && keyAvg > 160) { 
       key = "G#maj"; 
      } 
      else if (keyAvg <=180 && keyAvg > 170) { 
       key = "G#min"; 
      } 
      else if (keyAvg <=190 && keyAvg > 180) { 
       key = "Amaj"; 
      } 
      else if (keyAvg <=200 && keyAvg > 190) { 
       key = "Amin"; 
      } 
      else if (keyAvg <=210 && keyAvg > 200) { 
       key = "A#maj"; 
      } 
      else if (keyAvg <=220 && keyAvg > 210) { 
       key = "A#min"; 
      } 
      else if (keyAvg <=230 && keyAvg > 220) { 
       key = "Bmaj"; 
      } 
      else { 
       key = "Bmin"; 
      } 
      int tempoVal = 0; 
      int tempobase = img.getRGB(2, 2); 
      int tempored = (tempobase & 0x00ff0000) >> 16; 
      int tempogreen = (tempobase & 0x0000ff00) >> 8; 
      int tempoblue = tempobase & 0x000000ff; 
      if (tempored > tempogreen && tempored > tempoblue) { 
       tempoVal = tempored; 
      } 
      else if (tempogreen > tempored && tempogreen > tempoblue) { 
       tempoVal = tempogreen; 
      } 
      else if (tempoblue > tempored && tempoblue > tempogreen) { 
       tempoVal = tempoblue; 
      } 
      else { 
       tempoVal = 120; 
      } 
      String tempo = "T" + String.valueOf(tempoVal) + " "; 
      String inst; 
      int instbase = img.getRGB(3, 3); 
      int red5 = (instbase & 0x00ff0000) >> 16; 
      int green5 = (instbase & 0x0000ff00) >> 8; 
      int blue5 = instbase & 0x000000ff; 
      int instAvg = (red5 + green5 + blue5)/3; 
      if (instAvg > 111) { 
       instAvg = instAvg/2; 
       inst = "I" + String.valueOf(instAvg) + " "; 
      } 
      else { 
       inst = "I" + String.valueOf(instAvg) + " "; 
      } 
      for (int i = 0; i < width; i++) { 
       for (int j = 0; j < height; j++) { 
        int note = img.getRGB(i, j); 
        int red = (note & 0x00ff0000) >> 16; 
        int green = (note & 0x0000ff00) >> 8; 
        int blue = note & 0x000000ff; 
        int noteAvg = (red + green + blue)/3; 
        if (noteAvg >= 127) { 
         noteAvg = noteAvg/2; 
        } 
        String nAvg = String.valueOf(noteAvg); 
        i++; 
        int len = img.getRGB(i, j); 
        int red2 = (len & 0x00ff0000) >> 16; 
        int green2 = (len & 0x0000ff00) >> 8; 
        int blue2 = len & 0x000000ff; 
        int noteAvg2 = (red2 + green2 + blue2)/3; 
        String noteLen; 
        String keyVar = null; 
        if (noteAvg2 <= 42) { 
         noteLen = "W"; 
        } 
        else if (noteAvg2 <= (42 * 2) && noteAvg2 > 42) { 
         noteLen = "H"; 
        } 
        else if (noteAvg2 <= (42 * 3) && noteAvg2 > (42 * 2)) { 
         noteLen = "Q"; 
        } 
        else if (noteAvg2 <= (42 * 4) && noteAvg2 > (42 * 3)) { 
         noteLen = "I"; 
        } 
        else if (noteAvg2 <= (42 * 5) && noteAvg2 > (42 * 4)) { 
         noteLen = "S"; 
        } 
        else { 
         noteLen = "T"; 
        } 
        i++; 
        int keyvarbase = img.getRGB(i, j); 
        int red4 = (keyvarbase & 0x00ff0000) >> 16; 
        int green4 = (keyvarbase & 0x0000ff00) >> 8; 
        int blue4 = keyvarbase & 0x000000ff; 
        int noteAvg4 = (red4 + green4 + blue4)/3; 
        int findKeyVar = noteAvg4 % 4; 
        if (findKeyVar == 1) { 
         keyVar = "min"; 
        } 
        else if (findKeyVar == 2) { 
         keyVar = "maj"; 
        } 
        else if (findKeyVar == 3) { 
         keyVar = "aug"; 
        } 
        else { 
         keyVar = "dim"; 
        } 
        i++; 
        int inv = img.getRGB(i, j); 
        int red3 = (inv & 0x00ff0000) >> 16; 
        int green3 = (inv & 0x0000ff00) >> 8; 
        int blue3 = inv & 0x000000ff; 
        int noteAvg3 = (red3 + green3 + blue3)/3; 
        String inversion = null; 
        if (noteAvg3 <= (85 * 2) && noteAvg3 > 85) { 
         inversion = "^"; 
        } 
        else if (noteAvg3 <= (85 * 3) && noteAvg3 > (85 * 2)) { 
         inversion = "^^"; 
        } 
        if (noteAvg == 0) { 

        } 
        else { 
         String forPlayer = tempo + inst + "K" + key + " [" + nAvg + "]" + keyVar + noteLen; 
         midi.add(forPlayer); 
         midi.add("_"); 
         player.play(forPlayer); 
        } 
        i--; 
        i--; 
        i--; 
       } 
      } 
     } catch (IOException ex) { 
      Logger.getLogger(I2MC.class.getName()).log(Level.SEVERE, null, ex); 
     } 

나는 JFugue API를 사용하고있다.

답변

2

어느

for (int i = 0; i < width - 3; i++) { // Will use index i+3 

또는 if의. 단일 루프 단계의 시작

당신은 세 번 루프 내부 i++을하고 인덱스로 i를 사용할 때

, 그리고 이후 세 번 i--, , 내가 + 3 유효한 인덱스로 폭보다 작아야합니다. 코드를 읽기 쉽게 만들 수

final int i1 = i + 1; 
final int i2 = i + 2; 
final int i3 = i + 3; 

를 사용

당신의 스타일은 세심한이지만

. // 윌 {

을 위해 (내가 + + I = 0 int로, 나는 < 폭) :

i++을 가진 알고리즘 증거가 더 복잡 할 것이고, 같이 : 이제 경우에

// Define VALID_I(index) = (0 <= index < width) 

for (int i = 0; i < width - 3; i++) { // Will use index i+3 
    // Step pre-condition: 0 <= i < width - 3} => VALID_I(i) 
    ... getRGG(i, j); 
    i++; 
    // 1 <= i < width - 2 => VALID_I(i) 
    i++; 
    // 1 <= 2 < width - 1 => VALID_I(i) 
    i++; 
    // 1 <= 3 < width => VALID_I(i) 
    i -= 3; 
    // Step post-condition: 0 <= i < width - 3} => VALID_I(i) 
    // Loop-invariant: Step post-condition == step pre-codition 
} 

대체 = i < 너비 = => VALID_I (i) ... getRGG (i, j); i ++; // 1 < = i < width + 1 => VALID_I (i) if (i + 1> = width) 중단; // 1 < = i < width => VALID_I (i) i ++; if (i + 1> = width) 중단; // 2 < = i < width => VALID_I (i) i ++; if (i + 1> = width) 중단; // 3 < = i < width = e> VALID_I (i) i - = 3; // 0 < = 난 < 폭 - 3 => VALID_I (I) // 단계 후의 상태 : 0 = 1 < < 폭 - 3} => VALID_I (I) // 루프 불변 스텝 포스트 조건 == 단계 전처리 }

중첩 된 ifs와 대체합니다.

이 세 가지 대안은 i> = width - 3에 대해 다른 동작을합니다.

+1

당신의 대답은 정확 합니다만, 나는 당신이 내가 실제로 당신을 이해할 수 있기 전에 제 대답을 지울 수 있도록 이러한 행동을 선택한 이유에 대해 더 자세히 설명 할 수 있습니다.) – MadProgrammer

+0

@MadProgrammer : 일반 대중은 오류가 단지 감시 일 뿐이라고 생각합니다. –

관련 문제