我正在尝试加载ICO文件,但我似乎在图像数据大小和图像数据偏移值中得到奇怪的值,导致ArrayOutOfBoundsException。任何帮助表示赞赏。我试过Little / Big endian但没有成功。我找到了ICO结构的信息here。
代码:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
public class IcoFileReader {
public static void main(String[] args) {
URL url = null;
try {
url = new URL("https://www.google.be/favicon.ico");
} catch (MalformedURLException e) {
e.printStackTrace();
}
if(url == null) {
System.err.println("Url is null");
System.exit(-1);
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
final byte[] chunk = new byte[4096];
final InputStream stream = url.openStream();
int bytesRead;
while ((bytesRead = stream.read(chunk)) > 0) {
outputStream.write(chunk, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
final byte[] icoBytes = outputStream.toByteArray();
System.out.println("Ico bytes: " + Arrays.toString(icoBytes));
System.out.println("-- HEADER --");
System.out.println("Reserved: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 0, 2)));
System.out.println("Image type: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 2, 4)));
System.out.println("Num images: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 4, 6)));
System.out.println("");
System.out.println("-- BODY --");
System.out.println("Width: " + icoBytes[6]);
System.out.println("Height: " + icoBytes[7]);
System.out.println("Color Palette: " + icoBytes[8]);
System.out.println("Reserved: " + icoBytes[9]);
System.out.println("Color planes: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 10, 11)));
System.out.println("Bits per pixel: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 12, 13)));
System.out.println("Img data size: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 13, 17)) + " - " + ByteBuffer.wrap(Arrays.copyOfRange(icoBytes, 13, 17)).order(ByteOrder.LITTLE_ENDIAN).getInt());
System.out.println("Offset beginning data: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 17, 21)) + " - " + ByteBuffer.wrap(Arrays.copyOfRange(icoBytes, 17, 21)).order(ByteOrder.LITTLE_ENDIAN).getInt());
final int imgSize = ByteBuffer.wrap(Arrays.copyOfRange(icoBytes, 13, 17)).order(ByteOrder.LITTLE_ENDIAN).getInt();
final int offset = ByteBuffer.wrap(Arrays.copyOfRange(icoBytes, 17, 21)).order(ByteOrder.LITTLE_ENDIAN).getInt();
System.out.println("Bytes length: " + icoBytes.length);
System.out.println("Image data: " + Arrays.toString(Arrays.copyOfRange(icoBytes, offset, offset + imgSize)));
/* for(int i = 0; i < icoBytes[4]; i ++) {
final int start = (i * offset);
System.out.println("Image data: " + Arrays.toString(Arrays.copyOfRange(icoBytes, start, start + imgSize)));
}*/
}
}
输出:
- HEADER -
保留:[0,0]
图片类型:[1,0]
Num图片:[2,0]
- BODY -
宽度:16
身高:16
调色板:0
保留:0
颜色平面:1
每像素位数:[32]
Img数据大小:[0,104,4,0] - 288768
偏移开始数据:[0,38,0,0] - 9728
字节长度:5430
线程“main”中的异常java.lang.ArrayIndexOutOfBoundsException
答案 0 :(得分:0)
你被绊倒了。
System.out.println("Color planes: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 10, 12)));
System.out.println("Bits per pixel: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 12, 14)));
System.out.println("Img data size: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 14, 18)) + " - " + ByteBuffer.wrap(Arrays.copyOfRange(icoBytes, 14, 18)).order(ByteOrder.LITTLE_ENDIAN).getInt());
System.out.println("Offset beginning data: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 18, 22)) + " - " + ByteBuffer.wrap(Arrays.copyOfRange(icoBytes, 18, 22)).order(ByteOrder.LITTLE_ENDIAN).getInt());
final int imgSize = ByteBuffer.wrap(Arrays.copyOfRange(icoBytes, 14, 18)).order(ByteOrder.LITTLE_ENDIAN).getInt();
final int offset = ByteBuffer.wrap(Arrays.copyOfRange(icoBytes, 18, 22)).order(ByteOrder.LITTLE_ENDIAN).getInt();
(使用ByteBuffer可以在没有显式索引的情况下允许顺序读取;并且只设置字节顺序一次。)