다음을 통해 공유


썸네일 처리기 빌드

Windows Vista를 기준으로 이전 버전의 Windows보다 파일별 썸네일 이미지로 더 많이 사용합니다. 모든 보기, 대화 상자 및 이를 제공하는 모든 파일 형식에 사용됩니다. 축소판 그림 표시도 변경되었습니다. 아이콘 및 썸네일과 같은 개별 크기 대신 사용자가 선택할 수 있는 크기의 연속 스펙트럼을 사용할 수 있습니다.

IThumbnailProvider 인터페이스는 썸네일 제공을 이전 IExtractImage 또는 IExtractImage2보다 더 간단하게 만듭니다. 그러나 IExtractImage 또는 IExtractImage2 사용하는 기존 코드는 여전히 유효하고 지원됩니다.

RecipeThumbnailProvider 예제

이 섹션에서 해부된 RecipeThumbnailProvider 샘플은 Windows SDK(소프트웨어 개발 키트)에 포함되어 있습니다. 기본 설치 위치는 C:\Program Files\Microsoft SDKs\Windows\v6.0\Samples\WinUI\Shell\AppShellIntegration\RecipeThumbnailProvider입니다. 그러나 코드의 대부분도 여기에 포함되어 있습니다.

RecipeThumbnailProvider 샘플은 .recipe 확장 프로그램에 등록된 새 파일 형식에 대한 썸네일 처리기의 구현을 보여 줍니다. 이 샘플에서는 다른 썸네일 처리기 API를 사용하여 사용자 지정 파일 형식에 대한 썸네일 추출 COM(구성 요소 개체 모델) 서버를 등록하는 방법을 보여 줍니다. 이 항목에서는 코딩 선택 사항 및 지침을 강조 표시하는 샘플 코드를 안내합니다.

썸네일 처리기는 항상 다음 인터페이스 중 하나와 함께 IThumbnailProvider구현해야 합니다.

스트림을 사용하여 초기화할 수 없는 경우가 있습니다. 썸네일 처리기가 IInitializeWithStream을 구현하지 않는 경우, 스트림 변경 시 시스템 인덱서가 기본적으로 격리된 프로세스에 배치하는 것에서 제외해야 합니다. 프로세스 격리 기능을 옵트아웃하려면 다음 레지스트리 값을 설정합니다.

HKEY_CLASSES_ROOT
   CLSID
      {The CLSID of your thumbnail handler}
         DisableProcessIsolation = 1

IInitializeWithStream 구현하고 스트림 기반 초기화를 수행하는 경우 처리기가 더 안전하고 안정적입니다. 일반적으로 프로세스 격리를 사용하지 않도록 설정하는 것은 레거시 처리기에만 사용됩니다. 새 코드에 대해 이 기능을 사용하지 않도록 설정하지 마세요. IInitializeWithStream 가능하면 첫 번째 초기화 인터페이스 선택이어야 합니다.

샘플의 이미지 파일이 .recipe 파일에 포함되지 않고 파일 스트림의 일부가 아니므로 IInitializeWithItem 샘플에 사용됩니다. IInitializeWithItem::Initialize 메서드의 구현은 해당 매개 변수를 프라이빗 클래스 변수에 전달하기만 하면 됩니다.

IThumbnailProvider는 이미지의 최대 크기를 픽셀 단위로 지정하여 호출하는 하나의 메서드인GetThumbnail만을 포함하고 있습니다. 매개 변수의 이름은 cx 있지만 해당 값은 이미지의 x 및 y 차원의 최대 크기로 사용됩니다. 검색된 축소판 그림이 정사각형이 아닌 경우 긴 축은 cx 의해 제한되고 원래 이미지의 가로 세로 비율이 유지됩니다.

반환될 때, GetThumbnail는 검색된 이미지에 대한 핸들을 제공합니다. 또한 이미지의 색 형식과 유효한 알파 정보가 있는지 여부를 나타내는 값을 제공합니다.

샘플의 GetThumbnail 구현은 프라이빗 _GetBase64EncodedImageString 메서드 호출로 시작합니다.

IFACEMETHODIMP CRecipeThumbProvider::GetThumbnail(UINT cx, 
                                                  HBITMAP *phbmp, 
                                                  WTS_ALPHATYPE *pdwAlpha)
{
    PWSTR pszBase64EncodedImageString;
    HRESULT hr = _GetBase64EncodedImageString(cx, &pszBase64EncodedImageString);

.recipe 파일 형식은 고유한 파일 이름 확장명으로 등록된 XML 파일일 뿐입니다. 이 파일에는 이 특정 .recipe 파일의 썸네일로 사용할 이미지의 상대 경로 및 파일 이름을 제공하는 Picture라는 요소가 포함되어 있습니다. Picture 요소는 base 64로 인코딩된 이미지를 지정하는 Source 특성과 선택적 Size 특성으로 구성됩니다.

크기 작은 값과 큰 값이 있습니다. 이렇게 하면 여러 Picture 노드에 별도의 이미지를 제공할 수 있습니다. 그런 다음 검색된 이미지는 GetThumbnail호출에 제공된 최대 크기 값(cx)에 따라 달라집니다. Windows는 이미지 크기를 최대 크기보다 크게 조정하지 않으므로 다양한 해상도에 대해 다른 이미지를 제공할 수 있습니다. 그러나 간단히 하기 위해 샘플에서는 Size 특성을 생략하고 모든 상황에 대해 하나의 이미지만 제공합니다.

구현이 여기에 표시된 _GetBase64EncodedImageString 메서드는 XML DOM(문서 개체 모델) API를 사용하여 Picture 노드를 검색합니다. 해당 노드에서 원본 특성 데이터에서 이미지를 추출합니다.

HRESULT CRecipeThumbProvider::_GetBase64EncodedImageString(UINT /* cx */, 
                                                           PWSTR *ppszResult)
{
    *ppszResult = NULL;

    IXMLDOMDocument *pXMLDoc;
    HRESULT hr = _LoadXMLDocument(&pXMLDoc);
    if (SUCCEEDED(hr))
    {
        BSTR bstrQuery = SysAllocString(L"Recipe/Attachments/Picture");
        hr = bstrQuery ? S_OK : E_OUTOFMEMORY;
        if (SUCCEEDED(hr))
        {
            IXMLDOMNode *pXMLNode;
            hr = pXMLDoc->selectSingleNode(bstrQuery, &pXMLNode);
            if (SUCCEEDED(hr))
            {
                IXMLDOMElement *pXMLElement;
                hr = pXMLNode->QueryInterface(&pXMLElement);
                if (SUCCEEDED(hr))
                {
                    BSTR bstrAttribute = SysAllocString(L"Source");
                    hr = bstrAttribute ? S_OK : E_OUTOFMEMORY;
                    if (SUCCEEDED(hr))
                    {
                        VARIANT varValue;
                        hr = pXMLElement->getAttribute(bstrAttribute, &varValue);
                        if (SUCCEEDED(hr))
                        {
                            if ((varValue.vt == VT_BSTR) && varValue.bstrVal && varValue.bstrVal[0])
                            {
                                hr = SHStrDupW(varValue.bstrVal, ppszResult);
                            }
                            else
                            {
                                hr = E_FAIL;
                            }
                            VariantClear(&varValue);
                        }
                        SysFreeString(bstrAttribute);
                    }
                    pXMLElement->Release();
                }
                pXMLNode->Release();
            }
            SysFreeString(bstrQuery);
        }
        pXMLDoc->Release();
    }
    return hr;
}

GetThumbnail 그런 다음 검색된 문자열을 _GetStreamFromString전달합니다.

IFACEMETHODIMP CRecipeThumbProvider::GetThumbnail(UINT cx, 
                                                  HBITMAP *phbmp, 
                                                  WTS_ALPHATYPE *pdwAlpha)
{
    PWSTR pszBase64EncodedImageString;
    HRESULT hr = _GetBase64EncodedImageString(cx, &pszBase64EncodedImageString);
    if (SUCCEEDED(hr))
    {
        IStream *pImageStream;
        hr = _GetStreamFromString(pszBase64EncodedImageString, &pImageStream);

인코딩된 이미지를 스트림으로 변환하는 구현이 여기에 표시되는 _GetStreamFromString 메서드입니다.

HRESULT CRecipeThumbProvider::_GetStreamFromString(PCWSTR pszImageName, 
                                                   IStream **ppImageStream)
{
    HRESULT hr = E_FAIL;

    DWORD dwDecodedImageSize = 0;
    DWORD dwSkipChars        = 0;
    DWORD dwActualFormat     = 0;

    // Base64-decode the string
    BOOL fSuccess = CryptStringToBinaryW(pszImageName, 
                                         NULL, 
                                         CRYPT_STRING_BASE64,
                                         NULL, 
                                         &dwDecodedImageSize, 
                                         &dwSkipChars, 
                                         &dwActualFormat);
    if (fSuccess)
    {
        BYTE *pbDecodedImage = (BYTE*)LocalAlloc(LPTR, dwDecodedImageSize);
        if (pbDecodedImage)
        {
            fSuccess = CryptStringToBinaryW(pszImageName, 
                                            lstrlenW(pszImageName), 
                                            CRYPT_STRING_BASE64,
                                            pbDecodedImage, 
                                            &dwDecodedImageSize, 
                                            &dwSkipChars, 
                                            &dwActualFormat);
            if (fSuccess)
            {
                *ppImageStream = SHCreateMemStream(pbDecodedImage, 
                                                   dwDecodedImageSize);
                if (*ppImageStream != NULL)
                {
                    hr = S_OK;
                }
            }
            LocalFree(pbDecodedImage);
        }
    }
    return hr;
}

GetThumbnail WIC(Windows 이미징 구성 요소) API를 사용하여 스트림에서 비트맵을 추출하고 해당 비트맵에 대한 핸들을 가져옵니다. 알파 정보가 설정되고, WIC가 제대로 종료되고, 메서드가 성공적으로 종료됩니다.

IFACEMETHODIMP CRecipeThumbProvider::GetThumbnail(UINT cx, 
                                                  HBITMAP *phbmp, 
                                                  WTS_ALPHATYPE *pdwAlpha)
{
    PWSTR pszBase64EncodedImageString;
    HRESULT hr = _GetBase64EncodedImageString(cx, &pszBase64EncodedImageString);
    if (SUCCEEDED(hr))
    {
        IStream *pImageStream;
        hr = _GetStreamFromString(pszBase64EncodedImageString, &pImageStream);
        if (SUCCEEDED(hr))
        {
            hr = WICCreate32BitsPerPixelHBITMAP(pImageStream, 
                                                cx, 
                                                phbmp, 
                                                pdwAlpha);

            pImageStream->Release();
        }
        CoTaskMemFree(pszBase64EncodedImageString);
    }
    return hr;
}

썸네일 처리기

썸네일 처리기 지침

IID_PPV_ARGS