提问人:Cardinal System 提问时间:11/17/2023 更新时间:11/17/2023 访问量:50
setIconImages 会改变图像大小吗?
Does setIconImages change the image size?
问:
对于概念验证,我使用带有单例列表的 Window#setIconImages(List<? extends Image>)
将 16x16 图标添加到 JFrame
。在一个单独的程序中,我利用本机函数提取窗口的图标(请参阅将 HICON 转换为 Java 图像)并将其保存到文件中。生成的图像是 32x32 像素而不是 16x16,并且图像失去了一些质量:
我想确定图像放大的位置,看看我是否可以防止质量损失。也就是说,我想确定其底层本机调用是否正在更改图像,或者是否从本机窗口提供图标的函数负责此升级。setIconImages
我正在使用以下代码检索图标句柄:
private static HICON getIconHandle(HWND window) {
final DWORDByReference hIconNumber = new DWORDByReference();
LRESULT result = User32.INSTANCE.SendMessageTimeout(window, WinUser.WM_GETICON, new WPARAM(WinUser.ICON_BIG),
new LPARAM(0), WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber);
if (result.intValue() == 0)
result = User32.INSTANCE.SendMessageTimeout(window, WinUser.WM_GETICON, new WPARAM(WinUser.ICON_SMALL),
new LPARAM(0), WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber);
if (result.intValue() == 0)
result = User32.INSTANCE.SendMessageTimeout(window, WinUser.WM_GETICON, new WPARAM(WinUser.ICON_SMALL2),
new LPARAM(0), WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber);
if (result.intValue() == 0) {
result = new LRESULT(User32.INSTANCE.GetClassLongPtr(window, WinUser.GCLP_HICON).intValue());
hIconNumber.getValue().setValue(result.intValue());
}
if (result.intValue() == 0) {
result = new LRESULT(User32.INSTANCE.GetClassLongPtr(window, WinUser.GCLP_HICONSM).intValue());
hIconNumber.getValue().setValue(result.intValue());
}
if (result.intValue() == 0)
return null;
return new HICON(new Pointer(hIconNumber.getValue().longValue()));
}
我正在使用以下代码将图标转换为图像:
public static BufferedImage toImage(WinDef.HICON hicon) {
WinDef.HBITMAP bitmapHandle = null;
User32 user32 = User32.INSTANCE;
GDI32 gdi32 = GDI32.INSTANCE;
try {
WinGDI.ICONINFO info = new WinGDI.ICONINFO();
if (!user32.GetIconInfo(hicon, info))
return null;
info.read();
bitmapHandle = Optional.ofNullable(info.hbmColor).orElse(info.hbmMask);
WinGDI.BITMAP bitmap = new WinGDI.BITMAP();
if (gdi32.GetObject(bitmapHandle, bitmap.size(), bitmap.getPointer()) > 0) {
bitmap.read();
int width = bitmap.bmWidth.intValue();
int height = bitmap.bmHeight.intValue();
final WinDef.HDC deviceContext = user32.GetDC(null);
WinGDI.BITMAPINFO bitmapInfo = new WinGDI.BITMAPINFO();
bitmapInfo.bmiHeader.biSize = bitmapInfo.bmiHeader.size();
if (gdi32.GetDIBits(deviceContext, bitmapHandle, 0, 0, Pointer.NULL, bitmapInfo,
WinGDI.DIB_RGB_COLORS) == 0)
throw new IllegalArgumentException("GetDIBits should not return 0");
bitmapInfo.read();
Memory pixels = new Memory(bitmapInfo.bmiHeader.biSizeImage);
bitmapInfo.bmiHeader.biCompression = WinGDI.BI_RGB;
bitmapInfo.bmiHeader.biHeight = -height;
if (gdi32.GetDIBits(deviceContext, bitmapHandle, 0, bitmapInfo.bmiHeader.biHeight, pixels, bitmapInfo,
WinGDI.DIB_RGB_COLORS) == 0)
throw new IllegalArgumentException("GetDIBits should not return 0");
int[] colorArray = pixels.getIntArray(0, width * height);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
image.setRGB(0, 0, width, height, colorArray, 0, width);
return image;
}
} finally {
gdi32.DeleteObject(hicon);
Optional.ofNullable(bitmapHandle).ifPresent(gdi32::DeleteObject);
}
return null;
}
在那之后,它只是一个很好的老式 ImageIO.write(RenderedImage, String, File)
调用。
故障点在哪里?
答: 暂无答案
评论
SetIconSize
确实会更改该列表中所有图像的大小。SetIconSize