Bitmap erstellen und speichern?
-
So nach 2 Stunden Google versuch ich es mal hier. Ich versuche ein neues Bitmap zu erstellen, Text reinzuschreiben und anschließend zu speichern. Code bisher:
//create new bitmap HBITMAP hbitmap = CreateBitmap (48,48,4,8,NULL); BITMAP bm; GetObject (hbitmap, sizeof(BITMAP), &bm ); long width=bm.bmWidth; long height=bm.bmHeight; //prepare the bitmap attributes BITMAPINFO bmInfo; memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER)); bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bmInfo.bmiHeader.biWidth=width; bmInfo.bmiHeader.biHeight=height; bmInfo.bmiHeader.biPlanes=1; bmInfo.bmiHeader.biBitCount=24; //create a temporary dc in memory. HDC pDC = ::GetDC(0); HDC TmpDC=CreateCompatibleDC(pDC); //create a new bitmap and select it in the memory dc BYTE *pbase; HBITMAP TmpBmp=CreateDIBSection(pDC, &bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0); HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp); //draw the background HDC dcBmp=CreateCompatibleDC(TmpDC); HGDIOBJ TmpObj2 = SelectObject(dcBmp,hbitmap); BitBlt(TmpDC,0,0,width,height,dcBmp,0,0,SRCCOPY); SelectObject(TmpDC,TmpObj2); DeleteDC(dcBmp); //choose the font CFont m_Font; LOGFONT* m_pLF; m_pLF=(LOGFONT*)calloc(1,sizeof(LOGFONT)); strncpy(m_pLF->lfFaceName,"Times New Roman",31); m_pLF->lfHeight=64; m_pLF->lfWeight=600; m_pLF->lfItalic=1; m_pLF->lfUnderline=0; m_Font.CreateFontIndirect(m_pLF); //select the font in the dc CDC dc; dc.Attach(TmpDC); CFont* pOldFont=NULL; if (m_Font.m_hObject) pOldFont = dc.SelectObject(&m_Font); else dc.SelectObject(GetStockObject(DEFAULT_GUI_FONT)); //Set text color dc.SetTextColor(RGB(60,120,240)); //Set text position; RECT pos = {40,40,0,0}; //draw the text dc.SetBkMode(TRANSPARENT); dc.DrawText("Test",4,&pos,DT_CALCRECT); dc.DrawText("Test",4,&pos,0); //cleanup if (pOldFont) dc.SelectObject(pOldFont); m_Font.DeleteObject(); dc.Detach(); free(m_pLF); DeleteObject(hbitmap); hbitmap=TmpBmp; //final cleanup SelectObject(TmpDC,TmpObj); DeleteDC(TmpDC);
So weit so gut nur weiß ich nicht wie man das ganze jetzt als bmp-Datei abspeichert. Ich finde weder in der MSDN, noch bei Google oder hier im Forum eine halbwegs verständliche Lösung. Muss man dazu eine externe Bibliothek verwenden? Entwicklungsumgebung ist Visual Studio .NET 2003
-
Hier ein Beispiel aus dem Forum
http://www.c-plusplus.net/forum/viewtopic.php?t=61114&postdays=0&postorder=asc&start=0Und hier ein Beispiel aus der FAQ
http://www.c-plusplus.net/forum/viewtopic.php?t=39400&sid=fc6665b3a85eb08782a621eccc48680aGruß
:: NoName ::
-
Danke erstmal für die Hilfe.
So viel zum Thema das gäbe es nicht *hust*BOOL WriteBitmap( LPTSTR szFile, HBITMAP hbitmap, HDC memdc) { BITMAP bmp; if(GetObject(hbitmap, sizeof(BITMAP), &bmp)) { BITMAPINFOHEADER BmpInfoHdr; BITMAPFILEHEADER BmpFileHdr; BmpInfoHdr.biSize = sizeof(BITMAPINFOHEADER); BmpInfoHdr.biWidth = bmp.bmWidth; BmpInfoHdr.biHeight = bmp.bmHeight; BmpInfoHdr.biPlanes = bmp.bmPlanes; BmpInfoHdr.biBitCount = 24; BmpInfoHdr.biCompression = BI_RGB; BmpInfoHdr.biSizeImage = bmp.bmWidth*bmp.bmHeight*3; BmpFileHdr.bfType = 0x4d42; BmpFileHdr.bfReserved1 = 0; BmpFileHdr.bfReserved2 = 0; BmpFileHdr.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof (BITMAPINFOHEADER); BmpFileHdr.bfSize = BmpFileHdr.bfOffBits+BmpInfoHdr.biSizeImage; bmp.bmBits = (void*)GlobalAlloc(GMEM_FIXED, BmpInfoHdr.biSizeImage); if(GetDIBits(memdc, hbitmap, 0, BmpInfoHdr.biHeight, bmp.bmBits, (BITMAPINFO*)&BmpInfoHdr, DIB_RGB_COLORS) == BmpInfoHdr.biHeight) { HANDLE hFile = CreateFile(szFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL); if(hFile != INVALID_HANDLE_VALUE) { DWORD dwTmp; WriteFile(hFile, &BmpFileHdr, sizeof(BITMAPFILEHEADER), &dwTmp, NULL); WriteFile(hFile, &BmpInfoHdr, sizeof(BITMAPINFOHEADER), &dwTmp, NULL); WriteFile(hFile, bmp.bmBits, BmpInfoHdr.biSizeImage, &dwTmp, NULL); } CloseHandle(hFile); } GlobalFree(bmp.bmBits); return TRUE; } return FALSE; }
Wenn ich dem irgendeinen Pfad, TmpDC und hbitmap übergebe krieg ich zwar ein Bild, das ist aber einfach nur schwarz. Was mach ich falsch?
-
Hmm, vielleicht übergibst du das falsche HDC, versuchs mal mit pDC vom Typ HDC...
Gruß
:: NoName ::
-
Nö gibt das gleiche Verhalten. Ich poste einfach mal den gesamten Code:
// Paar Standard-Header und uninteressante defines // Function prototypes void GenerateBitmap (); BOOL WriteBitmap (LPTSTR szFile, HBITMAP hbitmap, HDC memdc); int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; // MFC initialisieren und drucken. Bei Fehlschlag Fehlermeldung aufrufen. if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { // TODO: Passen Sie den Fehlercode an Ihre Anforderungen an _tprintf(_T("Schwerwiegender Fehler: MFC-Initialisierung fehlgeschlagen\n")); nRetCode = 1; } else { GenerateBitmap(); } return nRetCode; } void GenerateBitmap () { //create new bitmap HBITMAP hbitmap = CreateBitmap (48,48,4,8,NULL); BITMAP bm; GetObject (hbitmap, sizeof(BITMAP), &bm ); long width=bm.bmWidth; long height=bm.bmHeight; //prepare the bitmap attributes BITMAPINFO bmInfo; memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER)); bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bmInfo.bmiHeader.biWidth=width; bmInfo.bmiHeader.biHeight=height; bmInfo.bmiHeader.biPlanes=1; bmInfo.bmiHeader.biBitCount=24; //create a temporary dc in memory. HDC pDC = ::GetDC(0); HDC TmpDC=CreateCompatibleDC(pDC); //create a new bitmap and select it in the memory dc BYTE *pbase; HBITMAP TmpBmp=CreateDIBSection(pDC, &bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0); HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp); //draw the background HDC dcBmp=CreateCompatibleDC(TmpDC); HGDIOBJ TmpObj2 = SelectObject(dcBmp,hbitmap); BitBlt(TmpDC,0,0,width,height,dcBmp,0,0,SRCCOPY); SelectObject(TmpDC,TmpObj2); DeleteDC(dcBmp); //choose the font CFont m_Font; LOGFONT* m_pLF; m_pLF=(LOGFONT*)calloc(1,sizeof(LOGFONT)); strncpy(m_pLF->lfFaceName,"Times New Roman",31); m_pLF->lfHeight=64; m_pLF->lfWeight=600; m_pLF->lfItalic=1; m_pLF->lfUnderline=0; m_Font.CreateFontIndirect(m_pLF); //select the font in the dc CDC dc; dc.Attach(TmpDC); CFont* pOldFont=NULL; if (m_Font.m_hObject) pOldFont = dc.SelectObject(&m_Font); else dc.SelectObject(GetStockObject(DEFAULT_GUI_FONT)); //Set text color dc.SetTextColor(RGB(60,120,240)); //Set text position RECT pos = {40,40,0,0}; //draw the text dc.SetBkMode(TRANSPARENT); dc.DrawText("Test",4,&pos,DT_CALCRECT); dc.DrawText("Test",4,&pos,0); //cleanup if (pOldFont) dc.SelectObject(pOldFont); m_Font.DeleteObject(); dc.Detach(); free(m_pLF); WriteBitmap ("Tmp.bmp", hbitmap, pDC); DeleteObject(hbitmap); hbitmap=TmpBmp; //final cleanup SelectObject(TmpDC,TmpObj); DeleteDC(TmpDC); } BOOL WriteBitmap( LPTSTR szFile, HBITMAP hbitmap, HDC memdc) { BITMAP bmp; if(GetObject(hbitmap, sizeof(BITMAP), &bmp)) { BITMAPINFOHEADER BmpInfoHdr; BITMAPFILEHEADER BmpFileHdr; BmpInfoHdr.biSize = sizeof(BITMAPINFOHEADER); BmpInfoHdr.biWidth = bmp.bmWidth; BmpInfoHdr.biHeight = bmp.bmHeight; BmpInfoHdr.biPlanes = bmp.bmPlanes; BmpInfoHdr.biBitCount = 24; BmpInfoHdr.biCompression = BI_RGB; BmpInfoHdr.biSizeImage = bmp.bmWidth*bmp.bmHeight*3; BmpFileHdr.bfType = 0x4d42; BmpFileHdr.bfReserved1 = 0; BmpFileHdr.bfReserved2 = 0; BmpFileHdr.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof (BITMAPINFOHEADER); BmpFileHdr.bfSize = BmpFileHdr.bfOffBits+BmpInfoHdr.biSizeImage; bmp.bmBits = (void*)GlobalAlloc(GMEM_FIXED, BmpInfoHdr.biSizeImage); if(GetDIBits(memdc, hbitmap, 0, BmpInfoHdr.biHeight, bmp.bmBits, (BITMAPINFO*)&BmpInfoHdr, DIB_RGB_COLORS) == BmpInfoHdr.biHeight) { HANDLE hFile = CreateFile(szFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL); if(hFile != INVALID_HANDLE_VALUE) { DWORD dwTmp; WriteFile(hFile, &BmpFileHdr, sizeof(BITMAPFILEHEADER), &dwTmp, NULL); WriteFile(hFile, &BmpInfoHdr, sizeof(BITMAPINFOHEADER), &dwTmp, NULL); WriteFile(hFile, bmp.bmBits, BmpInfoHdr.biSizeImage, &dwTmp, NULL); } CloseHandle(hFile); } GlobalFree(bmp.bmBits); return TRUE; } return FALSE; }
Vielleicht ist es auch einfach schon zu sehr Freitag und ich bin blind
-
Keiner eine Idee? Bin mittlerweile schon etwas verzweifelt.
-
Versuch es mal mit allen DC die du hast, irgendeiner muss doch gehen...(TmpDC)
-
Nein ich glaub ich mach grundsätzlich was falsch. Hab jetzt mal die DC2Bitmap Funktion hergenommen und ähnliche Ergebnisse. Anscheinend komm ich nicht drum herum dieses ganze GDI Zeug zu lernen bevor ich es gebacken kriege.
Wenn jemand helfen will: Ich brauch Code der mir ein neues Bitmap erstellt (irgendein kleines Ding) und mit einem Standardfont Text reinschreibt. Anschließend das ganze als Bmp-Datei (monochrom) speichern. Nichts mit Transparenz, Kompresssion oder sonst was nur stupides 48x48 bmp mit Text drin.
-
Kurze Auflösung für alle Interessierten:
Bibliothek runterladen:
http://www.codeproject.com/bitmap/cximage.aspAlternativer Code:
void GenerateBitmap () { //Create a new image CxImage image; image.Create(640,480,24,CXIMAGE_FORMAT_BMP); if (image.IsValid()) { //Preparing long width = image.GetWidth(); long height = image.GetHeight(); BITMAPINFO bmInfo; memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER)); bmInfo.bmiHeader.biSize =sizeof(BITMAPINFOHEADER); bmInfo.bmiHeader.biWidth = width; bmInfo.bmiHeader.biHeight = height; bmInfo.bmiHeader.biPlanes = 1; bmInfo.bmiHeader.biBitCount = 24; BYTE *pbase; //points to the final dib //get the background HDC pDC = ::GetDC(0); HDC TmpDC = CreateCompatibleDC(pDC); HBITMAP TmpBmp = CreateDIBSection(pDC,&bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0); HGDIOBJ TmpObj = SelectObject(TmpDC,TmpBmp); //draw the background image.Draw(TmpDC); //choose the font CFont m_Font; LOGFONT* m_pLF; m_pLF=(LOGFONT*)calloc(1,sizeof(LOGFONT)); strncpy(m_pLF->lfFaceName,"Times New Roman",31); m_pLF->lfHeight=64; m_pLF->lfWeight=600; m_pLF->lfItalic=1; m_pLF->lfUnderline=0; m_Font.CreateFontIndirect(m_pLF); //select the font in the dc CDC dc; dc.Attach(TmpDC); CFont* pOldFont=NULL; if (m_Font.m_hObject) pOldFont = dc.SelectObject(&m_Font); else dc.SelectObject(GetStockObject(DEFAULT_GUI_FONT)); //Set text color dc.SetTextColor(RGB(60,120,240)); //Set text position; RECT pos = {40,40,0,0}; //draw the text dc.SetBkMode(TRANSPARENT); dc.DrawText("Test",4,&pos,DT_CALCRECT); dc.DrawText("Test",4,&pos,0); //cleanup if (pOldFont) dc.SelectObject(pOldFont); m_Font.DeleteObject(); dc.Detach(); free(m_pLF); //transfer the result in the image CxImage tmpimage; tmpimage.CreateFromHBITMAP(TmpBmp); tmpimage.DecreaseBpp(image.GetBpp(),0,image.GetPalette()); image.Transfer(tmpimage); image.Save("tmp.bmp", CXIMAGE_FORMAT_BMP); //cleanup DeleteObject(SelectObject(TmpDC,TmpObj)); DeleteDC(TmpDC); } }