empilhar erro ao tentar modificar dados HBITMAP

votos
0

Eu estou tentando modificar um HBITMAP para adicionar pixels transparentes antes de torná-la (mas essa não é a questão) e depois de algum googling eu não posso mak meu código para trabalhar. Isso é o que estou tentando:

HBITMAP hBitmap = NULL, hBitmapOld = NULL;
HDC hMemDC = NULL;
BLENDFUNCTION bf;


hMemDC = CreateCompatibleDC(hdc);

hBitmapOld = (HBITMAP)SelectObject(hMemDC, bitmap);

BITMAPINFO MyBMInfo = { 0 };
MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);

if (0 == GetDIBits(hMemDC, bitmap, 0, height, NULL, &MyBMInfo, DIB_RGB_COLORS))
    return;

// create the pixel buffer
BYTE* lpPixels = new BYTE[MyBMInfo.bmiHeader.biSizeImage];

if (0 == GetDIBits(hMemDC, bitmap, 0, height, lpPixels, &MyBMInfo, DIB_RGB_COLORS))
    return;

for (int i = 0; i < width*height; i++)//i know there's 4 bytes per pixel, it's just to try
    lpPixels[i] = 0;

if (0 == SetDIBits(hMemDC, bitmap, 0, height, lpPixels, &MyBMInfo, DIB_RGB_COLORS))
    return;

delete[] lpPixels;

bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 255; //transparency value between 0-255
bf.AlphaFormat = 0;

AlphaBlend(hdc, xabs, yabs, width, height, hMemDC, 0, 0, width, height, bf);

SelectObject(hMemDC, hBitmapOld);

DeleteDC(hMemDC);
DeleteObject(hBitmap);

Actualy eu só estou tentando definir o pixel para 0 que deve definir pixels pretos (eventualy transparentes) para um quarto da imagem (como eu só vou de 0 a W * x e pixels são 4 bytes).

Mas há alguma corrupção de dados de modo que quando essa função sai recebo uma exceção. Então meu código não está correto.

Posso dizer que o bitmap é bem carregado, e tenho a boa informação bitmap a partir GetDIBits.

obrigado

Publicado 20/10/2017 em 13:37
fonte usuário
Em outras línguas...                            


2 respostas

votos
1

De MSDN :

biSizeImage

O tamanho, em bytes, da imagem. Isto pode ser ajustado para zero para bitmaps BI_RGB. Se biCompression é BI_JPEG ou BI_PNG, biSizeImage indica o tamanho da memória intermédia de imagem JPEG ou PNG, respectivamente.

Então, eu suspeito que você crie variedade efetivamente vazia desde bitmaps normalmente não são comprimidos e sofre de estouro de buffer mais tarde.

Para obter requerem tamanho do buffer você deve verificar biCompressione, em seguida, (assumindo que é descompactado BI_RGB) multiplicambiWidth * biHeight * biBitCount / 8

Respondeu 20/10/2017 em 13:49
fonte usuário

votos
0

I folowwed o conselho de VTT, mas ainda não funcionou, parece que o problema veio do BITMAPINFOque não foi usado corretamente, então eu segui o caminho Microsoft faz aqui e ele funciona:

BITMAPINFOHEADER   bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = width;
bi.biHeight = height;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
if (0 == GetDIBits(hMemDC, bitmap, 0, height, NULL, (BITMAPINFO*)&bi, DIB_RGB_COLORS))
    return;

// create the pixel buffer
BYTE* lpPixels = new BYTE[bi.biWidth * bi.biHeight * bi.biBitCount / 8];

if (0 == GetDIBits(hMemDC, bitmap, 0, height, lpPixels, (BITMAPINFO*)&bi, DIB_RGB_COLORS))
    return;

for (int i = 0; i < width*height; i++)//i know there's 4 bytes per pixel, it's just to try
    lpPixels[i] = 0;

if (0 == SetDIBits(hMemDC, bitmap, 0, height, lpPixels, (BITMAPINFO*)&bi, DIB_RGB_COLORS))
    return;
Respondeu 20/10/2017 em 15:50
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more