Poupança JPEG imagem de tela como um tampão de byte em C
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.
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.