从Icon获取“XOR Mask”和“AND mask”

时间:2011-10-03 15:03:09

标签: java image swing graphics awt

我需要从图标(XOR Mask)文件中获取AND Mask.ICO

如果有人可以建议我如何从Java中做到这一点,那将是非常棒的。 如果没有,你知道任何可以获得这两个面具并允许你的应用程序 抛弃它们?

2 个答案:

答案 0 :(得分:2)

这篇文章Enhance Java GUIs with Windows Icons对格式有很好的解释,并且有一些源代码的链接。

答案 1 :(得分:0)

关于 Windows 图标图像文件格式 https://en.m.wikipedia.org/wiki/ICO_(file_format) 的维基百科文章非常简单。

共有三个部分,标题、条目和图像数据。头是 6 个字节。每个条目是 16 个字节。每个入口结构的偏移量8是一个Java整数,用于图像数据的偏移量

32 bitDepth 位图的图像数据没有 AND 掩码。如果是 24 bitDepth,则需要 XOR 颜色掩码和 1 bitDepth AND 掩码。

bytes[] openFile(String fname) throws Exception
{
 java.io.InputStream file = new java.io.FileInputStream(fname);
 bytes []bytes = new bytes[file.available()];
 file.read(bytes);
 file.close();
 return bytes;
}

//assumes 24 bitDepth
bytes[] getXorMask(bytes []ico)
{
 int i = 6 + 8;
 i = bytes[i+0] | (bytes[i+1]<<1) | (bytes[i+2]<<2) | (bytes[i+3]<<3);
 i += sizeof(BITMAPINFOHEADER); // WOW! NOT JAVA
 
 int width = bytes[6] == 0 ? 256 : bytes[6];
 int height = bytes[7] == 0 ? 256 : bytes[7];
 int sz = width * height * 3; // very presumptious
 byte []bytes = new byte[sz];

 for(int e=0; e<sz; ) bytes[e++] = ico[i++];

 return bytes;
}

bytes[] getAndMask(bytes []ico)
{
 int i = 6 + 8;
 i = bytes[i+0] | (bytes[i+1]<<1) | (bytes[i+2]<<2) | (bytes[i+3]<<3);
 i += sizeof(BITMAPINFOHEADER); // WOW! NOT JAVA
 
 int width = bytes[6] == 0 ? 256 : bytes[6];
 int height = bytes[7] == 0 ? 256 : bytes[7];
 int sz = width * height * 3; // very presumptious
 byte []bytes = new byte[sz];

 i += sz; // seek to monochrome mask

 // only works if bounds is multiple of 4
 sz = width/8 * height;
 for(int e=0; e<sz; ) bytes[e++] = ico[i++];

 return bytes;
}

前面的示例总是获取第一个图像条目。我也认为这是一个简单的实现,但 Java 对 BITMAPINFOHEADER 一无所知,而且这个结构是一个可变大小的结构。

编辑:

首先要感谢 Raymond Chen。他在 MSDN 上有一门关于图标的课程(第 1 部分 - 第 4 部分)。

进一步阅读 https://docs.microsoft.com/en-us/previous-versions/ms997538(v=msdn.10)?redirectedfrom=MSDN,表明 BITMAPINFOHEADER 结构应该是固定大小的。查看 struct BITMAPINFOHEADER 的 win32 定义。它的大小为 40 字节。

编辑: BITMAPINFOHEADER 结构体的第一个 DWORD 是结构体的大小,以 little endian 表示。