簡體   English   中英

如何在C ++中保留顏色深度的同時提取文件圖標並另存為.ico?

[英]How to extract file icon and save as .ico while preserving color depth in C++?

我可以提取文件的圖標並使用下面的腳本保存它,但是腳本將圖標保存為灰色(似乎是4位色深)。

如何在保留圖標原始顏色深度的同時保存圖標?

using namespace std;

#include <iostream>
#include <string>
#include <fstream>
#include <windows.h>

#include "commctrl.h"
#pragma comment(lib, "comctl32.lib")

#include <olectl.h>
#pragma comment(lib, "oleaut32.lib")

HRESULT SaveIcon(HICON hIcon, PCTSTR path) {
    // Create the IPicture intrface
    PICTDESC desc = { sizeof(PICTDESC) };
    desc.picType = PICTYPE_ICON;
    desc.icon.hicon = hIcon;
    IPicture* pPicture = 0;
    HRESULT hr = OleCreatePictureIndirect(&desc, IID_IPicture, FALSE, (void**)& pPicture);
    if (FAILED(hr)) return hr;

    // Create a stream and save the image
    IStream* pStream = 0;
    CreateStreamOnHGlobal(0, TRUE, &pStream);
    LONG cbSize = 0;
    hr = pPicture->SaveAsFile(pStream, TRUE, &cbSize);

    // Write the stream content to the file
    if (!FAILED(hr)) {
        HGLOBAL hBuf = 0;
        GetHGlobalFromStream(pStream, &hBuf);
        void* buffer = GlobalLock(hBuf);
        HANDLE hFile = CreateFile(path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
        if (!hFile) hr = HRESULT_FROM_WIN32(GetLastError());
        else {
            DWORD written = 0;
            WriteFile(hFile, buffer, cbSize, &written, 0);
            CloseHandle(hFile);
        }
        GlobalUnlock(buffer);
    }
    // Cleanup
    pStream->Release();
    pPicture->Release();
    return hr;

}

HICON GetIcon(PCTSTR pszFile)
{
    SHFILEINFO sfi;
    HIMAGELIST himl = reinterpret_cast<HIMAGELIST>(
        SHGetFileInfo(pszFile, 0, &sfi, sizeof(sfi),
            SHGFI_SYSICONINDEX));
    if (himl) {
        return ImageList_GetIcon(himl, sfi.iIcon, ILD_NORMAL);
    }
    else {
        return NULL;
    }
}

int main()
{
    string fileBaseName = "appName";
    wstring fileBaseNameWSTRING(fileBaseName.begin(), fileBaseName.end());

    HICON hIcon = GetIcon((fileBaseNameWSTRING + L".lnk").c_str());

    if (hIcon == NULL) {
        cout << "GetIcon failed" << endl;
        return 1;
    }
    else {
        HRESULT hr = SaveIcon(hIcon, (L"temp\\" + fileBaseNameWSTRING + L".ico").c_str());
        return hr;
    }
}

SaveIcon函數摘自以下頁面: 如何將HICON保存到.ico文件?

通常,圖標包含多個原始位深度以及多個分辨率。 返回HICON的API不會執行,它們從圖標中選擇單個圖像。

如果需要完整的文件, SHGFI_SYSICONINDEX SHGFI_ICONLOCATION更改為SHGFI_ICONLOCATION ,您將獲得帶有圖標+圖標索引的DLL路徑。

加載DLL,最好使用LoadLibraryEx API和LOAD_LIBRARY_AS_DATAFILE選項。

然后調用資源API, FindResource / LoadResource / SizeofResource / LockResource ,以獲取圖標的源數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM