Using a 256 x 256 Windows Vista icon in an application

前端 未结 5 1152
离开以前
离开以前 2020-12-08 09:03

I have an application which I have made a 256 x 256 Windows Vista icon for.

I was wondering how I would be able to use a 256x256 PNG file in the ico file used a

5条回答
  •  自闭症患者
    2020-12-08 09:09

    Having the same problem of displaying the 256*256*32 image from an ICO file in a picture box, I found the solution from SAL80 the most efficient one (and almost working). However, the original code doesn't support images stored as BMP (the large icon is usually PNG, but not always...).

    Here is my version for future references. The code to create the bitmap is also slightly simpler :

        /// 
        /// Extracts  the large Vista icon from a ICO file 
        /// 
        /// Bytes of the ICO file
        /// The large icon or null if not found
        private static Bitmap ExtractVistaIcon(byte[] srcBuf)
        {
            const int SizeIcondir = 6;
            const int SizeIcondirentry = 16;
    
            // Read image count from ICO header
            int iCount = BitConverter.ToInt16(srcBuf, 4);
    
            // Search for a large icon
            for (int iIndex = 0; iIndex < iCount; iIndex++)
            {
                // Read image information from image directory entry
                int iWidth = srcBuf[SizeIcondir + SizeIcondirentry * iIndex];
                int iHeight = srcBuf[SizeIcondir + SizeIcondirentry * iIndex + 1];
                int iBitCount = BitConverter.ToInt16(srcBuf, SizeIcondir + SizeIcondirentry * iIndex + 6);
    
                // If Vista icon
                if (iWidth == 0 && iHeight == 0 && iBitCount == 32)
                {
                    // Get image data position and length from directory
                    int iImageSize = BitConverter.ToInt32(srcBuf, SizeIcondir + SizeIcondirentry * iIndex + 8);
                    int iImageOffset = BitConverter.ToInt32(srcBuf, SizeIcondir + SizeIcondirentry * iIndex + 12);
    
                    // Check if the image has a PNG signature
                    if (srcBuf[iImageOffset] == 0x89 && srcBuf[iImageOffset+1] == 0x50 && srcBuf[iImageOffset+2] == 0x4E && srcBuf[iImageOffset+3] == 0x47)
                    {
                        // the PNG data is stored directly in the file
                        var x = new MemoryStream(srcBuf, iImageOffset, iImageSize, false, false);
                        return new Bitmap(x); 
                    }
    
                    // Else it's bitmap data with a partial bitmap header
                    // Read size from partial header
                    int w = BitConverter.ToInt32(srcBuf, iImageOffset + 4);
                    // Create a full header
                    var b = new Bitmap(w, w, PixelFormat.Format32bppArgb);
                    // Copy bits into bitmap
                    BitmapData bmpData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.WriteOnly, b.PixelFormat);
                    Marshal.Copy(srcBuf, iImageOffset + Marshal.SizeOf(typeof(Bitmapinfoheader)), bmpData.Scan0, b.Width*b.Height*4);
                    b.UnlockBits(bmpData);
                    return b;
                }
            }
    
            return null;
        }
    

提交回复
热议问题