Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Есть dc c битмапом, как сохранить этот битмап в файл?

7.3K
25 ноября 2005 года
LamerMFC
48 / / 17.09.2005
Всем доброго времени суток.

Есть следующий вопрос:

Есть 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);

т.о. получается картинка пересекаемая линией по диагонали, как мне ее сохранить в файл?
(метафайлы не подходят)

заранее большое спасибо!
7.3K
28 ноября 2005 года
LamerMFC
48 / / 17.09.2005
Цитата:
Originally posted by LamerMFC
Всем доброго времени суток.

Есть следующий вопрос:

Есть 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 в котором и будет мой измененный битмап. вопрос: как мне этот измененный битмап сохранить на диск?

9.2K
28 ноября 2005 года
llllDeadMan
32 / / 28.11.2005
Цитата:
Originally posted by LamerMFC
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);
Просто функция, которую ты приводил используется для снятия скриншота окна, переделай ее под себя и все...

7.3K
29 ноября 2005 года
LamerMFC
48 / / 17.09.2005
Цитата:
Originally posted by llllDeadMan
Зачем тебе GetClientRect? Ты же используешь область 90x90, ну и задавай Rect ручками:
CRect rect(10, 10, 100, 100);
Просто функция, которую ты приводил используется для снятия скриншота окна, переделай ее под себя и все...



мне нужно получить битмап не с области на экране, а с метафайла, в который записан битмап

9.2K
29 ноября 2005 года
llllDeadMan
32 / / 28.11.2005
Цитата:
Originally posted by LamerMFC
мне нужно получить битмап не с области на экране, а с метафайла, в который записан битмап


Ну ты же можешь с метафайла считать в контекст устройства... И уже дальше работать именно с контекстом... И вообще не пойму зачем тебе этот метафайл...

7.3K
29 ноября 2005 года
LamerMFC
48 / / 17.09.2005
Цитата:
Originally posted by llllDeadMan
Ну ты же можешь с метафайла считать в контекст устройства... И уже дальше работать именно с контекстом... И вообще не пойму зачем тебе этот метафайл...



а как по другому нанести на битмап, ну скажем овал, а потом сохранить этот битмап с овалом на диск?

292
29 ноября 2005 года
Matush
726 / / 14.01.2004
У меня тоже как-то возникла проблема с сохранением HBITMAP'а в файл. Оказывается нет тако функции (см. http://forum.codenet.ru/showthread.php?threadid=26733)

Но это все просто решается. В МСДН описано. Если надо могу закинуть исходник по сохранению HBITMAP'а в файл (на API).
7.3K
30 ноября 2005 года
LamerMFC
48 / / 17.09.2005
Цитата:
Originally posted by Matush
У меня тоже как-то возникла проблема с сохранением HBITMAP'а в файл. Оказывается нет тако функции (см. http://forum.codenet.ru/showthread.php?threadid=26733)

Но это все просто решается. В МСДН описано. Если надо могу закинуть исходник по сохранению HBITMAP'а в файл (на API).



я на верху (2й пост) привел ф-цию StoreBitmapFile которая сохраняет битмап в файл. мне же надо:
1) нарисовать на битмапе (к примеру)линию без использования окон (для этого я использую метафайл);
2) сохранить этот отредактированный битмап (т.е. с линией не нем) в файл.

вроде все просто, а уже 3й день голову ломаю

9.2K
30 ноября 2005 года
llllDeadMan
32 / / 28.11.2005
Эх, ну почему люди думать не хотят... =)
Вот лови... Может быть немного криво, в твою функцию особо не вникал, но все работает, подправишь, доделаешь как тебе надо... ;)
Будут вопросы пиши...

P.S.> А где ты эти функции нашел подскажи?
7.3K
02 декабря 2005 года
LamerMFC
48 / / 17.09.2005
Цитата:
Originally posted by llllDeadMan

P.S.> А где ты эти функции нашел подскажи?



http://forum.sources.ru/index.php?showtopic=72768&st=15

7.3K
02 декабря 2005 года
LamerMFC
48 / / 17.09.2005
конечно большое спасибо.

dc=CreateCompatibleDC(GetDC(0));
я так понимаю что это хандел экрана, я так уже пытался:( но блин это как то кривовато, вот я и затеял всю кашу с метафайлом, хотя если с ним ничего не получится, то прийдется делать именно так:(
9.2K
02 декабря 2005 года
llllDeadMan
32 / / 28.11.2005
Цитата:
Originally posted by LamerMFC
конечно большое спасибо.

dc=CreateCompatibleDC(GetDC(0));
я так понимаю что это хандел экрана, я так уже пытался:( но блин это как то кривовато, вот я и затеял всю кашу с метафайлом, хотя если с ним ничего не получится, то прийдется делать именно так:(


Почти... Если быть точным - это создается хэндл на основе экранного, на самом деле кривого в этом ничего нет, т.к. сам экран не используется....
А про метафайл забудь - это полный глюк!!! =)

7.3K
03 декабря 2005 года
LamerMFC
48 / / 17.09.2005
Цитата:
Originally posted by llllDeadMan
А про метафайл забудь - это полный глюк!!! =)



Видимо придется, а жаль. Думаю вопрос исчерпан.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог