Накидал по-быстрому.
Код:
#include <stdio.h>
#include <windows.h>
BITMAPINFO* Open24DIB(const TCHAR* filename);
BOOL Save24DIB(const TCHAR* filename, BITMAPINFO* dib);
void Draw24DIB(HDC hDC, int x, int y, BITMAPINFO* dib);
void Free24DIB(BITMAPINFO* dib);
int main(){
BITMAPINFO* dib = Open24DIB(TEXT("C:\\src.bmp"));
if(dib == NULL)
return 1;
RGBTRIPLE* rgb;
BYTE step;
BYTE* ptr = (PBYTE)dib + *(DWORD*)dib;
for(long y = 0L; y < dib->bmiHeader.biHeight; y++) {
step = (BYTE)MulDiv(y, 255, dib->bmiHeader.biHeight);
for(long x = 0L; x < dib->bmiHeader.biWidth; x++) {
rgb = (RGBTRIPLE*)((ptr) + (y * dib->bmiHeader.biWidth + x) * sizeof(RGBTRIPLE));
rgb->rgbtRed = max(rgb->rgbtRed - step, 0);
rgb->rgbtGreen = max(rgb->rgbtGreen - step, 0);
rgb->rgbtBlue = max(rgb->rgbtBlue - step, 0);
}
}
HWND w = GetForegroundWindow();
HDC d = GetDC(w);
Draw24DIB(d, 1, 1, dib);
ReleaseDC(w, d);
Save24DIB(TEXT("C:\\dst.bmp"), dib);
Free24DIB(dib);
getchar();
return 0;
}
BITMAPINFO* Open24DIB(const TCHAR* filename) {
HANDLE fp = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(fp == INVALID_HANDLE_VALUE)
return NULL;
BITMAPFILEHEADER finfo;
DWORD dread = 0uL;
ZeroMemory(&finfo, sizeof(BITMAPFILEHEADER));
ReadFile(fp, (LPVOID)&finfo, sizeof(BITMAPFILEHEADER), &dread, NULL);
if(finfo.bfType != 0x4D42) {
CloseHandle(fp);
return NULL;
}
BITMAPINFOHEADER info;
ZeroMemory(&info, sizeof(BITMAPINFOHEADER));
ReadFile(fp, (LPVOID)&info, sizeof(BITMAPINFOHEADER), &dread, NULL);
if((info.biBitCount != 24u) || (info.biCompression != BI_RGB)) {
CloseHandle(fp);
return NULL;
}
BITMAPINFO* dib = (BITMAPINFO*) new BYTE[finfo.bfSize];
if(dib == NULL) {
CloseHandle(fp);
return NULL;
}
SetFilePointer(fp, sizeof(BITMAPFILEHEADER), NULL, FILE_BEGIN);
ReadFile(fp, (LPVOID)dib, finfo.bfSize, &dread, NULL);
CloseHandle(fp);
return dib;
}
BOOL Save24DIB(const TCHAR* filename, BITMAPINFO* dib) {
if(dib == NULL)
return FALSE;
HANDLE fp = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(fp == INVALID_HANDLE_VALUE)
return FALSE;
BITMAPFILEHEADER finfo;
DWORD dwrite = 0uL;
ZeroMemory(&finfo, sizeof(BITMAPFILEHEADER));
finfo.bfType = 0x4D42;
finfo.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
finfo.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dib->bmiHeader.biSizeImage;
WriteFile(fp, (LPCVOID)&finfo, sizeof(BITMAPFILEHEADER), &dwrite, NULL);
WriteFile(fp, (LPCVOID)&dib->bmiHeader, sizeof(BITMAPINFOHEADER), &dwrite, NULL);
PBYTE ptr = (PBYTE)dib + *(DWORD*)dib;
WriteFile(fp, (LPCVOID)ptr, dib->bmiHeader.biSizeImage, &dwrite, NULL);
FlushFileBuffers(fp);
CloseHandle(fp);
return TRUE;
}
void Draw24DIB(HDC hDC, int x, int y, BITMAPINFO* dib) {
if(dib == NULL)
return;
PBYTE ptr = (PBYTE)dib + *(DWORD*)dib;
SetDIBitsToDevice(hDC, x, y, dib->bmiHeader.biWidth, dib->bmiHeader.biHeight, 0, 0,
dib->bmiHeader.biPlanes, dib->bmiHeader.biHeight, (LPVOID)ptr, dib, 0);
}
void Free24DIB(BITMAPINFO* dib) {
if(dib == NULL)
return;
delete[] (LPBYTE)dib;
}