Pergunta

Em uma das minhas perguntas anteriores eu perguntei como tirar um screenshot e salvá-lo como JPEG sem o uso de GDI +, devido aos constrangimentos de ter que usar somente C. No final, eu respondi a pergunta a mim mesmo com a ajuda de de alguns dos comentários lá. Usando uma versão C muito concisa de GDI + (carregado em tempo de execução) eu posso tirar um screenshot e salve-o como um JPEG para um arquivo. Agora, como eu iria salvar essa mesma imagem não a um arquivo, mas a um buffer? um unsigned char * buffer? aqui está o código que precisa ser convertido.

int SaveJpeg(HBITMAP hBmp, LPCWSTR lpszFilename, ULONG uQuality)
{
    ULONG *pBitmap = NULL;
    CLSID imageCLSID;
    EncoderParameters encoderParams;
    int iRes = 0;

    typedef Status (WINAPI *pGdipCreateBitmapFromHBITMAP)(HBITMAP, HPALETTE, ULONG**);
    pGdipCreateBitmapFromHBITMAP lGdipCreateBitmapFromHBITMAP;

    typedef Status (WINAPI *pGdipSaveImageToFile)(ULONG *, const WCHAR*, const CLSID*, const EncoderParameters*);
    pGdipSaveImageToFile lGdipSaveImageToFile;

    // load GdipCreateBitmapFromHBITMAP
    lGdipCreateBitmapFromHBITMAP = (pGdipCreateBitmapFromHBITMAP)GetProcAddress(hModuleThread, "GdipCreateBitmapFromHBITMAP");
    if(lGdipCreateBitmapFromHBITMAP == NULL)
    {
        // error
        return 0;
    }

    // load GdipSaveImageToFile
    lGdipSaveImageToFile = (pGdipSaveImageToFile)GetProcAddress(hModuleThread, "GdipSaveImageToFile");
    if(lGdipSaveImageToFile == NULL)
    {
        // error
        return 0;
    }

        lGdipCreateBitmapFromHBITMAP(hBmp, NULL, &pBitmap);

       iRes = GetEncoderClsid(L"image/jpeg", &imageCLSID);
       if(iRes == -1)
    {
        // error
        return 0;
    }
    encoderParams.Count = 1;
    encoderParams.Parameter[0].NumberOfValues = 1;
    encoderParams.Parameter[0].Guid  = EncoderQuality;
    encoderParams.Parameter[0].Type  = EncoderParameterValueTypeLong;
    encoderParams.Parameter[0].Value = &uQuality;

    lGdipSaveImageToFile(pBitmap, lpszFilename, &imageCLSID, &encoderParams);


    return 1;
}

Obrigado pela ajuda.

Foi útil?

Solução

Em vez de chamar GdipSaveImageToFile, você deve usar GdipSaveImageToStream. Isso permitirá que você salvar a imagem em um fluxo diretamente, em vez de escrevê-lo em um arquivo.

Veja a GDI funções imagem para mais detalhes.

A fim de criar um IStream na memória, você pode usar CreateStreamOnHGlobal . Isto tem a opção de permitir que o IStream para alocar sua própria memória, ou para usar um buffer pré-alocado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top