refer:http://stackoverflow.com/questions/2289894/how-can-i-save-hicon-to-an-ico-file

answer1:

 1 #include "stdafx.h"
 2 #include <windows.h>
 3 #include <olectl.h>
 4 #pragma comment(lib, "oleaut32.lib")
 5 
 6 HRESULT SaveIcon(HICON hIcon, const wchar_t* path) {
 7     // Create the IPicture intrface
 8     PICTDESC desc = { sizeof(PICTDESC) };
 9     desc.picType = PICTYPE_ICON;
10     desc.icon.hicon = hIcon;
11     IPicture* pPicture = 0;
12     HRESULT hr = OleCreatePictureIndirect(&desc, IID_IPicture, FALSE, (void**)&pPicture);
13     if (FAILED(hr)) return hr;
14 
15     // Create a stream and save the image
16     IStream* pStream = 0;
17     CreateStreamOnHGlobal(0, TRUE, &pStream);
18     LONG cbSize = 0;
19     hr = pPicture->SaveAsFile(pStream, TRUE, &cbSize);
20 
21     // Write the stream content to the file
22     if (!FAILED(hr)) {
23         HGLOBAL hBuf = 0;
24         GetHGlobalFromStream(pStream, &hBuf);
25         void* buffer = GlobalLock(hBuf);
26         HANDLE hFile = CreateFile(path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
27         if (!hFile) hr = HRESULT_FROM_WIN32(GetLastError());
28         else {
29             DWORD written = 0;
30             WriteFile(hFile, buffer, cbSize, &written, 0);
31             CloseHandle(hFile);
32         }
33         GlobalUnlock(buffer);
34     }
35     // Cleanup
36     pStream->Release();
37     pPicture->Release();
38     return hr;
39 
40 }
41 int _tmain(int argc, _TCHAR* argv[])
42 {
43     HICON hIcon = (HICON)LoadImage(0, L"c:\\windows\\system32\\perfcentercpl.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
44     if (!hIcon) return GetLastError();
45     HRESULT hr = SaveIcon(hIcon, L"c:\\temp\\test.ico");
46     return hr;
47 }

answer2:

  1 #include <afx.h>
  2 #include <afxwin.h>
  3 #include <atlbase.h>
  4 
  5 struct ICONDIRENTRY
  6 {
  7     UCHAR nWidth;
  8     UCHAR nHeight;
  9     UCHAR nNumColorsInPalette; // 0 if no palette
 10     UCHAR nReserved; // should be 0
 11     WORD nNumColorPlanes; // 0 or 1
 12     WORD nBitsPerPixel;
 13     ULONG nDataLength; // length in bytes
 14     ULONG nOffset; // offset of BMP or PNG data from beginning of file
 15 };
 16 
 17 // Helper class to release GDI object handle when scope ends:
 18 class CGdiHandle
 19 {
 20 public:
 21     CGdiHandle(HGDIOBJ handle) : m_handle(handle) {};
 22     ~CGdiHandle(){DeleteObject(m_handle);};
 23 private:
 24     HGDIOBJ m_handle;
 25 };
 26 
 27 
 28 // Save icon referenced by handle 'hIcon' as file with name 'szPath'.
 29 // The generated ICO file has the color depth specified in 'nColorBits'.
 30 //
 31 bool SaveIcon(HICON hIcon, int nColorBits, const TCHAR* szPath)
 32 {
 33     ASSERT(nColorBits == 4 || nColorBits == 8 || nColorBits == 24 || nColorBits == 32);
 34 
 35     if (offsetof(ICONDIRENTRY, nOffset) != 12)
 36     {
 37         return false;
 38     }
 39 
 40     CDC dc;
 41     dc.Attach(::GetDC(NULL)); // ensure that DC is released when function ends
 42 
 43     // Open file for writing:
 44     CFile file;
 45     if (!file.Open(szPath, CFile::modeWrite | CFile::modeCreate))
 46     {
 47         return false;
 48     }
 49 
 50     // Write header:
 51     UCHAR icoHeader[6] = {0, 0, 1, 0, 1, 0}; // ICO file with 1 image
 52     file.Write(icoHeader, sizeof(icoHeader));
 53 
 54     // Get information about icon:
 55     ICONINFO iconInfo;
 56     GetIconInfo(hIcon, &iconInfo);
 57     CGdiHandle handle1(iconInfo.hbmColor), handle2(iconInfo.hbmMask); // free bitmaps when function ends
 58     BITMAPINFO bmInfo = {0};
 59     bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 60     bmInfo.bmiHeader.biBitCount = 0;    // don't get the color table     
 61     if (!GetDIBits(dc, iconInfo.hbmColor, 0, 0, NULL, &bmInfo, DIB_RGB_COLORS))
 62     {
 63         return false;
 64     }
 65 
 66     // Allocate size of bitmap info header plus space for color table:
 67     int nBmInfoSize = sizeof(BITMAPINFOHEADER);
 68     if (nColorBits < 24)
 69     {
 70         nBmInfoSize += sizeof(RGBQUAD) * (int)(1 << nColorBits);
 71     }
 72 
 73     CAutoVectorPtr<UCHAR> bitmapInfo;
 74     bitmapInfo.Allocate(nBmInfoSize);
 75     BITMAPINFO* pBmInfo = (BITMAPINFO*)(UCHAR*)bitmapInfo;
 76     memcpy(pBmInfo, &bmInfo, sizeof(BITMAPINFOHEADER));
 77 
 78     // Get bitmap data:
 79     ASSERT(bmInfo.bmiHeader.biSizeImage != 0);
 80     CAutoVectorPtr<UCHAR> bits;
 81     bits.Allocate(bmInfo.bmiHeader.biSizeImage);
 82     pBmInfo->bmiHeader.biBitCount = nColorBits;
 83     pBmInfo->bmiHeader.biCompression = BI_RGB;
 84     if (!GetDIBits(dc, iconInfo.hbmColor, 0, bmInfo.bmiHeader.biHeight, (UCHAR*)bits, pBmInfo, DIB_RGB_COLORS))
 85     {
 86         return false;
 87     }
 88 
 89     // Get mask data:
 90     BITMAPINFO maskInfo = {0};
 91     maskInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 92     maskInfo.bmiHeader.biBitCount = 0;  // don't get the color table     
 93     if (!GetDIBits(dc, iconInfo.hbmMask, 0, 0, NULL, &maskInfo, DIB_RGB_COLORS))
 94     {
 95         return false;
 96     }
 97     ASSERT(maskInfo.bmiHeader.biBitCount == 1);
 98     CAutoVectorPtr<UCHAR> maskBits;
 99     maskBits.Allocate(maskInfo.bmiHeader.biSizeImage);
100     CAutoVectorPtr<UCHAR> maskInfoBytes;
101     maskInfoBytes.Allocate(sizeof(BITMAPINFO) + 2 * sizeof(RGBQUAD));
102     BITMAPINFO* pMaskInfo = (BITMAPINFO*)(UCHAR*)maskInfoBytes;
103     memcpy(pMaskInfo, &maskInfo, sizeof(maskInfo));
104     if (!GetDIBits(dc, iconInfo.hbmMask, 0, maskInfo.bmiHeader.biHeight, (UCHAR*)maskBits, pMaskInfo, DIB_RGB_COLORS))
105     {
106         return false;
107     }
108 
109     // Write directory entry:
110     ICONDIRENTRY dir;
111     dir.nWidth = (UCHAR) pBmInfo->bmiHeader.biWidth;
112     dir.nHeight = (UCHAR) pBmInfo->bmiHeader.biHeight;
113     dir.nNumColorsInPalette = (nColorBits == 4 ? 16 : 0);
114     dir.nReserved = 0;
115     dir.nNumColorPlanes = 0;
116     dir.nBitsPerPixel = pBmInfo->bmiHeader.biBitCount;
117     dir.nDataLength = pBmInfo->bmiHeader.biSizeImage + pMaskInfo->bmiHeader.biSizeImage + nBmInfoSize;
118     dir.nOffset = sizeof(dir) + sizeof(icoHeader);
119     file.Write(&dir, sizeof(dir));
120 
121     // Write DIB header (including color table):
122     int nBitsSize = pBmInfo->bmiHeader.biSizeImage;
123     pBmInfo->bmiHeader.biHeight *= 2; // because the header is for both image and mask
124     pBmInfo->bmiHeader.biCompression = 0;
125     pBmInfo->bmiHeader.biSizeImage += pMaskInfo->bmiHeader.biSizeImage; // because the header is for both image and mask
126     file.Write(&pBmInfo->bmiHeader, nBmInfoSize);
127 
128     // Write image data:
129     file.Write((UCHAR*)bits, nBitsSize);
130 
131     // Write mask data:
132     file.Write((UCHAR*)maskBits, pMaskInfo->bmiHeader.biSizeImage);
133 
134     file.Close();
135 
136     return true;
137 }
138 
139 // Test program for SaveIcon() function.
140 //
141 // Usage: first argument is input ICO file (must be 32x32 pixels); second argument is output ICO file
142 //
143 int _tmain(int argc, _TCHAR* argv[])
144 {
145     ASSERT(argc == 3);
146 
147     // Load a 32x32 icon:
148     HICON hIcon = (HICON)LoadImage(0, argv[1], IMAGE_ICON, 32, 32, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
149     ASSERT(hIcon != NULL);
150 
151     // Save with 24-bits colors:
152     if (!SaveIcon(hIcon, 24, argv[2]))
153     {
154         _ftprintf(stderr, _T("Error: saving icon to %s failed"), argv[2]);
155         return EXIT_FAILURE;
156     }
157 
158     return EXIT_SUCCESS;
159 }
View Code

相关文章:

  • 2021-06-29
  • 2021-12-19
  • 2021-09-14
  • 2022-01-15
  • 2021-05-30
  • 2020-03-23
  • 2022-12-23
  • 2021-08-21
猜你喜欢
  • 2022-12-23
  • 2021-11-29
  • 2022-12-23
  • 2021-09-21
  • 2022-12-23
  • 2021-08-28
  • 2022-12-23
相关资源
相似解决方案