2017-03-25 11 views
0

Windows Imaging Component를 사용하여 클립 보드에 복사 한 이미지를 읽는 기능을 작성하려고합니다. 현재 내 코드는 리소스를로드하는 방법을 기반으로하지만 클립 보드에서 작동하도록 수정되었습니다. 스트림을 초기화 할 때까지 모든 것이 잘 작동하지만 일단 사용하려고 시도하면 CreateDecoderFromeStream이 실패합니다. 나는 수많은 곳에서 이미지를 복사하는 것을 시도했지만 아무 소용이 없었다. WIC에서 읽을 수없는 복사 된 이미지 형식과 다른 점이 있습니까? 반환 된 스트림을 사용하여 클립 보드 다른 곳 코드에서WIC로 클립 보드 읽기

COMStreamSPtr WIC::createStreamFromClipboard() { 
    IStream* ipStream = NULL; 
    COMStreamSPtr stream = nullptr; 
    CoInitialize(nullptr); 
    if (!IsClipboardFormatAvailable(CF_BITMAP) && !IsClipboardFormatAvailable(CF_DIB) && !IsClipboardFormatAvailable(CF_DIBV5)) 
     goto Return; 

    if (!OpenClipboard(NULL)) 
     goto Return; 

    // Load the clipboard 
    HGLOBAL hMem = GetClipboardData(CF_BITMAP); 
    if (hMem == NULL || hMem == INVALID_HANDLE_VALUE) 
     hMem = GetClipboardData(CF_DIB); 
    if (hMem == NULL || hMem == INVALID_HANDLE_VALUE) 
     hMem = GetClipboardData(CF_DIBV5); 
    if (hMem == NULL || hMem == INVALID_HANDLE_VALUE) 
     goto CloseClipboard; 

    // Lock the clipboard, getting a pointer to its data 
    LPVOID pvSourceClipboardData = GlobalLock(hMem); 
    if (pvSourceClipboardData == NULL) 
     goto CloseClipboard; 

    // Read the clipboard data size 
    DWORD dwClipboardSize = GlobalSize(hMem); 
    if (dwClipboardSize == 0) 
     goto GlobalUnlock; 

    // Allocate memory to hold the clipboard data 
    HGLOBAL hgblClipboardData = GlobalAlloc(GMEM_MOVEABLE, dwClipboardSize); 
    if (hgblClipboardData == NULL) 
     goto GlobalUnlock; 

    // Get a pointer to the allocated memory 
    LPVOID pvClipboardData = GlobalLock(hgblClipboardData); 
    if (pvClipboardData == NULL) 
     goto FreeData; 

    // Copy the data from the clipboard to the new memory block 
    CopyMemory(pvClipboardData, pvSourceClipboardData, dwClipboardSize); 
    GlobalUnlock(hgblClipboardData); 

    // Create a stream on the HGLOBAL containing the data 
    if (SUCCEEDED(CreateStreamOnHGlobal(hgblClipboardData, TRUE, &ipStream))) { 
     stream = std::make_shared<COMStream>(ipStream); 
     goto CloseClipboard; 
    } 

FreeData: 
    // Couldn't create stream; free the memory 
    GlobalFree(hgblClipboardData); 
GlobalUnlock: 
    // Unlock the clipboard data 
    GlobalUnlock(hMem); 
CloseClipboard: 
    // Close the clipboard 
    CloseClipboard(); 
Return: 
    // No need to unlock or free the resource 
    CoUninitialize(); // CoInialize is called by my COMObjects in the constructor so this is just decrementing the count. 
    return stream; 
} 

에서 읽을 메모리 객체를 생성

여기 아래에있는 내 코드의

...

.

WICBitmapDecoderSPtr WIC::createDecoderFromStream(COMStreamSPtr stream) { 
    if (isCOMObjectNull(stream)) 
     return nullptr; 

    IWICImagingFactory* ipFactory = NULL; 
    IWICBitmapDecoder* ipDecoder = NULL; 
    WICBitmapDecoderSPtr decoder = nullptr; 

    // Create the factory 
    if (FAILED(CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ipFactory)))) 
     goto Return; 

    // Create the decoder 
    if (FAILED(ipFactory->CreateDecoderFromStream(stream->ipObject, NULL, WICDecodeMetadataCacheOnDemand, &ipDecoder))) 
     goto ReleaseFactory; // FAILS HERE 

    decoder = std::make_shared<WICBitmapDecoder>(ipDecoder); 
ReleaseFactory: 
    ipFactory->Release(); 
Return: 
    return decoder; 
} 

답변

0

나는 이것을 어떻게하는지 알아 냈습니다. 내가 한 것은 IWICImagingFactoryCreateBitmapFromHBITMAP 기능을 사용했습니다. clipboard에서 HBITMAP을 읽는 것이 쉽기 때문에이 솔루션은 매우 간단합니다.

IWICBitmapSource* WIC::readSourceFromClipboard() { 
    IWICBitmapSource* ipSource = NULL; 
    if (Clipboard::containsFormat(CF_BITMAP)) { 
     if (OpenClipboard(NULL)) { 
      HBITMAP hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP); 
      ipSource = createSourceFromHBitmap(hBitmap); 
      CloseClipboard(); 
     } 
    } 
    return ipSource; 
} 

IWICBitmapSource* WIC::createSourceFromHBitmap(HBITMAP hBitmap) { 
    if (hBitmap == NULL) 
     return NULL; 

    IWICImagingFactory* ipFactory = NULL; 
    IWICBitmap* ipBitmap = NULL; 

    CoInitialize(NULL); 

    // Create the factory 
    if (FAILED(CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ipFactory)))) 
     goto Return; 

    // Create the bitmap 
    if (FAILED(ipFactory->CreateBitmapFromHBITMAP(hBitmap, NULL, WICBitmapIgnoreAlpha, &ipBitmap))) 
     goto ReleaseFactory; 

ReleaseFactory: 
    ipFactory->Release(); 
Return: 
    CoUninitialize(); 
    return ipBitmap; 
}