JNA将HICON转换为Java映像

JNA将HICON转换为Java映像,java,c++,converter,jna,Java,C++,Converter,Jna,我不知道已经有一个。但它的解决方案不适合我,因为使用Sehellfolder方法只能得到16x16和32x32大小的图标。 我提取了一个大小为256x256的HICO,并希望将其转换为和Java图像类似的BuffereImage。我找到了它的方法。但它不能正常工作: public static BufferedImage getIcon(final WinDef.HICON hIcon,int ICON_SIZE,short ICON_DEPTH,int ICON_BYTE_SIZE) {

我不知道已经有一个。但它的解决方案不适合我,因为使用Sehellfolder方法只能得到16x16和32x32大小的图标。 我提取了一个大小为256x256的HICO,并希望将其转换为和Java图像类似的BuffereImage。我找到了它的方法。但它不能正常工作:

public static BufferedImage getIcon(final WinDef.HICON hIcon,int ICON_SIZE,short ICON_DEPTH,int ICON_BYTE_SIZE) {
    final int width = ICON_SIZE;
    final int height = ICON_SIZE;
    final short depth = ICON_DEPTH;
    final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

    final Memory lpBitsColor = new Memory(width * height * depth / ICON_BYTE_SIZE);
    final Memory lpBitsMask = new Memory(width * height * depth / ICON_BYTE_SIZE);
    final WinGDI.BITMAPINFO info = new WinGDI.BITMAPINFO();
    final WinGDI.BITMAPINFOHEADER hdr = new WinGDI.BITMAPINFOHEADER();
    info.bmiHeader = hdr;
    hdr.biWidth = width;
    hdr.biHeight = height;
    hdr.biPlanes = 1;
    hdr.biBitCount = depth;
    hdr.biCompression = WinGDI.BI_RGB;

    final WinDef.HDC hDC = User32.INSTANCE.GetDC(null);
    final WinGDI.ICONINFO piconinfo = new WinGDI.ICONINFO();
    User32.INSTANCE.GetIconInfo(hIcon, piconinfo);

    GDI32.INSTANCE.GetDIBits(hDC, piconinfo.hbmColor, 0, height, lpBitsColor, info, WinGDI.DIB_RGB_COLORS);
    GDI32.INSTANCE.GetDIBits(hDC, piconinfo.hbmMask, 0, height, lpBitsMask, info, WinGDI.DIB_RGB_COLORS);

    int r, g, b, a, argb;
    int x = 0, y = height - 1;
    for (int i = 0; i < lpBitsColor.size(); i = i + 3) {
        b = lpBitsColor.getByte(i) & 0xFF;
        g = lpBitsColor.getByte(i + 1) & 0xFF;
        r = lpBitsColor.getByte(i + 2) & 0xFF;
        a = 0xFF - lpBitsMask.getByte(i) & 0xFF;

        argb = a << 24 | r << 16 | g << 8 | b;
        image.setRGB(x, y, argb);
        x = (x + 1) % width;
        if (x == 0) {
            y--;
        }
    }

    User32.INSTANCE.ReleaseDC(null, hDC);
    GDI32.INSTANCE.DeleteObject(piconinfo.hbmColor);
    GDI32.INSTANCE.DeleteObject(piconinfo.hbmMask);

    return image;
}
public static buffereImage getIcon(final WinDef.HICON HICON,int图标大小,短图标深度,int图标字节大小){
最终整型宽度=图标大小;
最终整数高度=图标大小;
最终短深度=图标深度;
最终BuffereImage图像=新的BuffereImage(宽度、高度、BuffereImage.TYPE_INT_ARGB);
最终内存lpBitsColor=新内存(宽度*高度*深度/图标字节大小);
最终内存LPBITSMAK=新内存(宽度*高度*深度/图标字节大小);
final WinGDI.BITMAPINFO info=new WinGDI.BITMAPINFO();
final WinGDI.BitMapInfo头hdr=新WinGDI.BitMapInfo头();
info.bmiHeader=hdr;
hdr.biWidth=宽度;
hdr.biHeight=高度;
hdr.biPlanes=1;
hdr.biBitCount=深度;
hdr.biCompression=WinGDI.BI_RGB;
final WinDef.HDC HDC=User32.INSTANCE.GetDC(null);
final WinGDI.ICONINFO piconinfo=新WinGDI.ICONINFO();
User32.INSTANCE.GetIconInfo(hIcon,piconinfo);
GDI32.INSTANCE.GetDIBits(hDC,piconinfo.hbmColor,0,height,lpBitsColor,info,WinGDI.DIB_RGB_COLORS);
GDI32.INSTANCE.GetDIBits(hDC,piconinfo.hbmMask,0,height,lpBitsMask,info,WinGDI.DIB_RGB_COLORS);
int r,g,b,a,argb;
int x=0,y=高度-1;
对于(int i=0;iargb=a您需要使用本例中示例3的方法

您是否可以添加一个指向您参考的其他问题的链接作为上下文?我已经添加了该链接有人有解决方案吗?您是否可以更清楚地说明什么“无法正常工作”意思是?如果你看这张图片。很难看。你能在答案中包含代码并做一个简短的解释吗?这样,如果链接死了,答案仍然是相关的。而且,正如担心的那样,链接死了。对此我很抱歉。但我已经编写了我自己的库,它具有HICON到BuffereImage转换的功能。可以转换的旧版本这里有一个HICON。还有一个使用HBITMAP的更新版。我希望这有帮助。
public static BufferedImage getImageByHICON(final int width, final int height, final WinNT.HANDLE hicon, final WinGDI.BITMAPINFOHEADER info) {
    final WinGDI.ICONINFO iconinfo = new WinGDI.ICONINFO();

    try {
        // GDI32 g32 = GDI32.INSTANCE;

        // get icon information

        if (!User32.INSTANCE.GetIconInfo(new WinDef.HICON(hicon.getPointer()), iconinfo)) { return null; }
        final WinDef.HWND hwdn = new WinDef.HWND();
        final WinDef.HDC dc = User32.INSTANCE.GetDC(hwdn);

        if (dc == null) {

            return null; }
        try {
            final int nBits = width * height * 4;
            // final BitmapInfo bmi = new BitmapInfo(1);

            final Memory colorBitsMem = new Memory(nBits);
            // // Extract the color bitmap
            final WinGDI.BITMAPINFO bmi = new WinGDI.BITMAPINFO();

            bmi.bmiHeader.biWidth = width;
            bmi.bmiHeader.biHeight = -height;
            bmi.bmiHeader.biPlanes = 1;
            bmi.bmiHeader.biBitCount = 32;
            bmi.bmiHeader.biCompression = WinGDI.BI_RGB;
            GDI32.INSTANCE.GetDIBits(dc, iconinfo.hbmColor, 0, height, colorBitsMem, bmi, WinGDI.DIB_RGB_COLORS);
            // g32.GetDIBits(dc, iconinfo.hbmColor, 0, size, colorBitsMem,
            // bmi,
            // GDI32.DIB_RGB_COLORS);
            final int[] colorBits = colorBitsMem.getIntArray(0, width * height);
            if (info.biBitCount < 32) {
                final Memory maskBitsMem = new Memory(nBits);
                // // Extract the mask bitmap
                GDI32.INSTANCE.GetDIBits(dc, iconinfo.hbmMask, 0, height, maskBitsMem, bmi, WinGDI.DIB_PAL_COLORS);
                // g32.GetDIBits(dc, iconinfo.hbmMask, 0, size,
                // maskBitsMem,
                // bmi,
                // // GDI32.DIB_RGB_COLORS);
                final int[] maskBits = maskBitsMem.getIntArray(0, width * height);
                // // // Copy the mask alphas into the color bits
                for (int i = 0; i < colorBits.length; i++) {
                    colorBits[i] = colorBits[i] | (maskBits[i] != 0 ? 0 : 0xFF000000);
                }
            }
            final BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            bi.setRGB(0, 0, width, height, colorBits, 0, height);
            return bi;
        } finally {
            com.sun.jna.platform.win32.User32.INSTANCE.ReleaseDC(hwdn, dc);
        }
    } finally {
        User32.INSTANCE.DestroyIcon(new WinDef.HICON(hicon.getPointer()));
        GDI32.INSTANCE.DeleteObject(iconinfo.hbmColor);
        GDI32.INSTANCE.DeleteObject(iconinfo.hbmMask);
    }
}