Есть dc c битмапом, как сохранить этот битмап в файл?
Есть следующий вопрос:
Есть dc c битмапом и линиями на нем (т.е. я беру обычную картинку которая лежит на винте, например машину, и рисую на ней разные линии, круги, квадраты и т.д.), как сохранить этот битмап в файл? Т.е. до запуска программы была просто фотка, а после запуска уже измененная (с моими линиями и др. фигурами).
Делаю следующее:
dc и hBitmap уже есть.
CDC dcMem;
dcMem.m_hDC = CreateCompatibleDC(dc.m_hDC);
SelectObject(dcMem.m_hDC, hBitmap);
dc.BitBlt(10, 10, 100, 100, &dcMem, 0, 0, SRCCOPY);
dc.MoveTo(10,10);
dc.LineTo(100,100);
т.о. получается картинка пересекаемая линией по диагонали, как мне ее сохранить в файл?
(метафайлы не подходят)
заранее большое спасибо!
Всем доброго времени суток.
Есть следующий вопрос:
Есть dc c битмапом и линиями на нем (т.е. я беру обычную картинку которая лежит на винте, например машину, и рисую на ней разные линии, круги, квадраты и т.д.), как сохранить этот битмап в файл? Т.е. до запуска программы была просто фотка, а после запуска уже измененная (с моими линиями и др. фигурами).
Делаю следующее:
dc и hBitmap уже есть.
CDC dcMem;
dcMem.m_hDC = CreateCompatibleDC(dc.m_hDC);
SelectObject(dcMem.m_hDC, hBitmap);
dc.BitBlt(10, 10, 100, 100, &dcMem, 0, 0, SRCCOPY);
dc.MoveTo(10,10);
dc.LineTo(100,100);
т.о. получается картинка пересекаемая линией по диагонали, как мне ее сохранить в файл?
(метафайлы не подходят)
заранее большое спасибо!
попытка №2
Вот код с помощью которого можно взять dc и скопировать в файл:
BOOL StoreBitmapFile(LPCTSTR lpszFileName, HBITMAP HBM)
{
BITMAP BM;
BITMAPFILEHEADER BFH;
LPBITMAPINFO BIP;
HDC DC;
LPBYTE Buf;
DWORD ColorSize,DataSize;
WORD BitCount;
HANDLE FP;
DWORD dwTemp;
GetObject(HBM, sizeof(BITMAP), (LPSTR)&BM);
BitCount = (WORD)BM.bmPlanes * BM.bmBitsPixel;
switch (BitCount)
{
case 1:
case 4:
case 8:
case 32:
ColorSize = sizeof(RGBQUAD) * (1 << BitCount);
case 16:
case 24:
ColorSize = 0;
}
DataSize = ((BM.bmWidth*BitCount+31) & ~31)/8*BM.bmHeight;
BIP=(LPBITMAPINFO)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(BITMAPINFOHEADER)+ColorSize);
BIP->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BIP->bmiHeader.biWidth = BM.bmWidth;
BIP->bmiHeader.biHeight = BM.bmHeight;
BIP->bmiHeader.biPlanes = 1;
BIP->bmiHeader.biBitCount = BitCount;
BIP->bmiHeader.biCompression = 0;
BIP->bmiHeader.biSizeImage = DataSize;
BIP->bmiHeader.biXPelsPerMeter = 0;
BIP->bmiHeader.biYPelsPerMeter = 0;
if (BitCount < 16)
BIP->bmiHeader.biClrUsed = (1<<BitCount);
BIP->bmiHeader.biClrImportant = 0;
BFH.bfType = 0x4d42;
BFH.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ BIP->bmiHeader.biClrUsed * sizeof(RGBQUAD);
BFH.bfReserved1 = 0;
BFH.bfReserved2 = 0;
BFH.bfSize = BFH.bfOffBits + DataSize;
Buf = (LPBYTE)GlobalAlloc(GMEM_FIXED, DataSize);
DC = GetDC(0);
GetDIBits(DC, HBM, 0,(WORD)BM.bmHeight, Buf, BIP, DIB_RGB_COLORS);
ReleaseDC(0, DC);
FP=CreateFile(lpszFileName,GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
WriteFile(FP,&BFH,sizeof(BITMAPFILEHEADER),&dwTemp,NULL);
WriteFile(FP,BIP,sizeof(BITMAPINFOHEADER) + BIP->bmiHeader.biClrUsed * sizeof(RGBQUAD),&dwTemp,NULL);
WriteFile(FP,Buf,DataSize,&dwTemp,NULL);
CloseHandle(FP);
GlobalFree((HGLOBAL)Buf);
HeapFree(GetProcessHeap(),0,(LPVOID)BIP);
return(true);
}
HBITMAP CreateBitmap(HDC DC, int w, int h)
{
HDC memDC;
HBITMAP bm,oldBM;
memDC=CreateCompatibleDC(DC);
bm=CreateCompatibleBitmap(DC,w,h);
oldBM=(HBITMAP)SelectObject(memDC,bm);
BitBlt(memDC, 0,0, w, h, DC, 0,0, SRCCOPY);
SelectObject(memDC,oldBM);
DeleteDC(memDC);
DeleteObject(oldBM);
return bm;
}
HBITMAP CreateClientWindwowBitmap(HWND wnd)
{
RECT r;
GetClientRect(wnd,&r);
return(CreateBitmap(GetDC(wnd),r.right,r.bottom));
}
HBITMAP CreateWindwowBitmap(HWND wnd)
{
RECT r;
POINT pt;
GetWindowRect(wnd,&r);
pt.x=r.right;
pt.y=r.bottom;
ScreenToClient(wnd,&pt);
return(CreateBitmap(GetWindowDC(wnd),pt.x,pt.y));
}
HBITMAP CreateDesktopBitmap(void)
{
RECT r;
SystemParametersInfo(SPI_GETWORKAREA,0,&r,0);
return(CreateBitmap(GetDC(GetDesktopWindow()),r.right,r.bottom));
}
HBITMAP CreateScreenBitmap(void)
{
DWORD w,h;
HDC DC;
w=GetSystemMetrics(SM_CXSCREEN);
h=GetSystemMetrics(SM_CYSCREEN);
DC=CreateDC("DISPLAY", NULL, NULL, NULL);
return(CreateBitmap(DC,w,h));
DeleteDC(DC);
}
VOID StoreClientWindowBitmap(HWND wnd, LPCTSTR pszFileName)
{
HBITMAP bm;
bm=CreateClientWindwowBitmap(wnd);
StoreBitmapFile(pszFileName,bm);
DeleteObject(bm);
}
VOID StoreWindowBitmap(HWND wnd, LPCTSTR pszFileName)
{
HBITMAP bm;
bm=CreateWindwowBitmap(wnd);
StoreBitmapFile(pszFileName,bm);
DeleteObject(bm);
}
VOID StoreDesktopBitmap(LPCTSTR pszFileName)
{
HBITMAP bm;
bm=CreateDesktopBitmap();
StoreBitmapFile(pszFileName,bm);
DeleteObject(bm);
}
VOID StoreScreenBitmap(LPCTSTR pszFileName)
{
HBITMAP bm;
bm=CreateScreenBitmap();
StoreBitmapFile(pszFileName,bm);
DeleteObject(bm);
}
.....
void StoreAll(void)
{
StoreClientWindowBitmap(hDlg,"c:\\client.bmp"); // клиентская область окна
StoreWindowBitmap(hDlg,"c:\\window.bmp"); // окно
StoreDesktopBitmap("c:\\desktop.bmp"); // десктоп
StoreScreenBitmap("c:\\screen.bmp"); // экран
}
.....
т.е. что бы взять битмап окна надо сделать следующее
RECT r;
GetClientRect(wnd,&r);
return(CreateBitmap(GetDC(wnd),r.right,r.bottom));
где wnd - дескриптор окна.
но у меня приложение консольное, поэтому нет никаких окон. цель следующая - при запуске программы в командной стоке передается какой битмап будем обрабатывать (типа C:\car.bmp), и то, как мы это будем делать(ну там что будем рисовать на нем: линии, квадраты...). после того, как программа отработает, появляется еще один битмап, с именем (в нашем примере) car(edit).bmp. для того чтобы на нужном мне битмапе нарисовать линию я делаю следующее:
void DrawBitmap(CDC& dc, HBITMAP bmp)
{
CDC memdc;
BITMAP bm;
GetObject(bmp, sizeof(BITMAP), &bm);
memdc.m_hDC = CreateCompatibleDC(dc.m_hDC);
SelectObject(memdc.m_hDC, bmp);
dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memdc, 0, 0, SRCCOPY);
}
HENHMETAFILE hEMF;
CDC dcEMF;
dcEMF.m_hDC = CreateEnhMetaFile (NULL, "c:\\car(edit).emf", NULL, NULL);
HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, "c:\\car.bmp", IMAGE_BITMAP, NULL, NULL, LR_LOADFROMFILE | LR_DEFAULTSIZE);
DrawBitmap(dcEMF, hBitmap);
MoveTo(dcEMF.m_hDC, 0,0);
LineTo(dcEMF.m_hDC, 100,100);
hEMF = CloseEnhMetaFile(dcEMF.m_hDC);
DeleteEnhMetaFile(hEMF);
после этого на диске создается метафайл car(edit).emf в котором и будет мой измененный битмап. вопрос: как мне этот измененный битмап сохранить на диск?
CDC dcMem;
dcMem.m_hDC = CreateCompatibleDC(dc.m_hDC);
SelectObject(dcMem.m_hDC, hBitmap);
dc.BitBlt(10, 10, 100, 100, &dcMem, 0, 0, SRCCOPY);
dc.MoveTo(10,10);
dc.LineTo(100,100);
Зачем тебе GetClientRect? Ты же используешь область 90x90, ну и задавай Rect ручками:
CRect rect(10, 10, 100, 100);
Просто функция, которую ты приводил используется для снятия скриншота окна, переделай ее под себя и все...
Зачем тебе GetClientRect? Ты же используешь область 90x90, ну и задавай Rect ручками:
CRect rect(10, 10, 100, 100);
Просто функция, которую ты приводил используется для снятия скриншота окна, переделай ее под себя и все...
мне нужно получить битмап не с области на экране, а с метафайла, в который записан битмап
мне нужно получить битмап не с области на экране, а с метафайла, в который записан битмап
Ну ты же можешь с метафайла считать в контекст устройства... И уже дальше работать именно с контекстом... И вообще не пойму зачем тебе этот метафайл...
Ну ты же можешь с метафайла считать в контекст устройства... И уже дальше работать именно с контекстом... И вообще не пойму зачем тебе этот метафайл...
а как по другому нанести на битмап, ну скажем овал, а потом сохранить этот битмап с овалом на диск?
Но это все просто решается. В МСДН описано. Если надо могу закинуть исходник по сохранению HBITMAP'а в файл (на API).
У меня тоже как-то возникла проблема с сохранением HBITMAP'а в файл. Оказывается нет тако функции (см. http://forum.codenet.ru/showthread.php?threadid=26733)
Но это все просто решается. В МСДН описано. Если надо могу закинуть исходник по сохранению HBITMAP'а в файл (на API).
я на верху (2й пост) привел ф-цию StoreBitmapFile которая сохраняет битмап в файл. мне же надо:
1) нарисовать на битмапе (к примеру)линию без использования окон (для этого я использую метафайл);
2) сохранить этот отредактированный битмап (т.е. с линией не нем) в файл.
вроде все просто, а уже 3й день голову ломаю
Вот лови... Может быть немного криво, в твою функцию особо не вникал, но все работает, подправишь, доделаешь как тебе надо... ;)
Будут вопросы пиши...
P.S.> А где ты эти функции нашел подскажи?
P.S.> А где ты эти функции нашел подскажи?
dc=CreateCompatibleDC(GetDC(0));
я так понимаю что это хандел экрана, я так уже пытался:( но блин это как то кривовато, вот я и затеял всю кашу с метафайлом, хотя если с ним ничего не получится, то прийдется делать именно так:(
конечно большое спасибо.
dc=CreateCompatibleDC(GetDC(0));
я так понимаю что это хандел экрана, я так уже пытался:( но блин это как то кривовато, вот я и затеял всю кашу с метафайлом, хотя если с ним ничего не получится, то прийдется делать именно так:(
Почти... Если быть точным - это создается хэндл на основе экранного, на самом деле кривого в этом ничего нет, т.к. сам экран не используется....
А про метафайл забудь - это полный глюк!!! =)
А про метафайл забудь - это полный глюк!!! =)
Видимо придется, а жаль. Думаю вопрос исчерпан.