[英]Get Pixels from BufferedImage while Manipulating Height Value
I am currently writing a program to convert a BufferedImage
to music. 我目前正在编写一个程序,将BufferedImage
转换为音乐。 When I get the width and height of the BufferedImage
, the values are correct. 当我得到BufferedImage
的宽度和高度时,值是正确的。 However, inside the FOR
loop I am using to get the pixels, I am manipulating one of the FOR
loop values ( i++
). 但是,在FOR
循环中我用来获取像素,我正在操作其中一个FOR
循环值( i++
)。 At the end of the void
, I reset the values to their original state ( i--
). 在void
结束时,我将值重置为其原始状态( i--
)。 The program does not evaluate the entire image, but instead gives me this error: 该程序不会评估整个图像,而是给我这个错误:
java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
How should I fix this error? 我该如何解决这个错误? Here is my code: 这是我的代码:
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);
}
I am using the JFugue API. 我正在使用JFugue API。
Either 或
for (int i = 0; i < width - 3; i++) { // Will use index i+3
or if
s. 或者if
是。
As you thrice do i++
inside the loop and use i
as index, and afterwards thrice i--
, at the start of a single loop step, i+3 must be less than width to be a valid index. 因为你在循环中做了三次i++
并使用i
作为索引,然后三次i--
,在单个循环步骤的开始,i + 3必须小于width才能成为有效索引。
Though your style is meticulous, using 虽然你的风格很细致,但使用方式
final int i1 = i + 1;
final int i2 = i + 2;
final int i3 = i + 3;
might make the code more readable. 可能会使代码更具可读性。
An algorithmic proof with i++
would be more complex, and look like: 使用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
}
Alternative with if's: 替代if:
for (int i = 0; i < width; i++) { // Will use index i+3 // Step pre-condition: 0 <= i < width} <=> VALID_I(i) ... getRGG(i, j); for(int i = 0; i <width; i ++){//将使用索引i + 3 //步骤前置条件:0 <= i <width} <=> VALID_I(i)... getRGG(i, j)条; i++; 我++; // 1 <= i < width + 1 => VALID_I(i) if (i + 1 >= width) break; // 1 <= i <width + 1 => VALID_I(i)if(i + 1> = width)中断; // 1 <= i < width => VALID_I(i) i++; // 1 <= i <width => VALID_I(i)i ++; if (i + 1 >= width) break; if(i + 1> = width)中断; // 2 <= i < width => VALID_I(i) i++; // 2 <= i <width => VALID_I(i)i ++; if (i + 1 >= width) break; if(i + 1> = width)中断; // 3 <= i < width =e > VALID_I(i) i -= 3; // 3 <= i <width = e> VALID_I(i)i - = 3; // 0 <= i < width - 3 => VALID_I(i) // Step post-condition: 0 <= i < width - 3} => VALID_I(i) // Loop-invariant: Step post-condition == step pre-codition } // 0 <= i <width - 3 => VALID_I(i)//步骤后置条件:0 <= i <width - 3} => VALID_I(i)//循环不变:步骤后置条件==步骤预编码}
Alternative with nested ifs the same. 替代嵌套ifs相同。
These three alternatives have different behaviour for i >= width - 3. 对于i> = width - 3,这三种替代方案具有不同的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.