CBitmap



  • Hallo,

    ich habe (mal wieder) ein Problem mit Bitmaps:

    CDC     memDC; 
    CDC*    pDC = GetDC(); 
    CBitmap *pOldBitmap;   
    
    memDC.CreateCompatibleDC(pDC);
    (*Bitmap).CreateCompatibleBitmap(pDC, width, height); 
    pOldBitmap = memDC.SelectObject(Bitmap); 
    
    const int nXMIN = -100;
    const int nXMAX = 100;
    const int nYMIN = -100;
    const int nYMAX = 100;
    
    // Map-Mode auf LOENGLISH setzen
    memDC.SetMapMode(MM_LOENGLISH);
    
    // Neuer Nullpunkt
    CPoint     CZero(-nXMIN,nYMIN);
    // Verschiebung des Nullpunktes aufgrund Mapping-Mode ausrechnen
    memDC.LPtoDP(&CZero);
    memDC.SetViewportOrg(CZero);
    
    // Routine für's zeichnen	
    
    memDC.SelectObject(pOldBitmap);
    ReleaseDC(&memDC);
    

    Der Code ist soweit in Ordnung, aber der Hintergrund ist schwarz.

    Mit

    memDC.FillSolidRect(0, 0, width, height, RGB(255,255,255)); // weisser Hintergrund
    

    bekomme ich nun einen weissen Hintergrund .. und die Anwendung läuft. 👍

    Jetzt ist es so, dass die Bitmap ziemlich groß ist. 32467 x 480.
    Wenn ich das Programm beende, dann geht die Prozessorauslastung nach oben und es dauert ewig bis es sich beendet.

    Ohne

    memDC.FillSolidRect(0, 0, width, height, RGB(255,255,255)); // weisser Hintergrund
    

    geht's wesentlich schneller, mit dem kleinen Nachteil, dass der Hintergrund schwarz ist 👎

    Habt Ihr vielleicht eine Idee, weshalb dieses Problem auftritt? Oder einen Vorschlag/Tipp..

    Vielen Dank



  • hab leider keine ahnung aber ich koennte dir was bitmaps angeht vielleicht mit fertigem code aushelfen
    je nachdem was du brauchst...

    aber eine frage habe ich: was'n "LOENGLISH"??? 😃

    schau dir vielleicht mal folgenden code an und vielleicht findest du was raus
    die int CTest1Dlg::dc2bitmap(HDC hdc, HBITMAP aBmp, LPTSTR szFile2) methode ist fuer screenshots eines ausschnitts in monochrome
    und die bool CTest1Dlg::WriteBitmap(LPTSTR szFile, HBITMAP hbitmap, HDC memdc) fuer screenshots in 24bitRGB
    schlecht kommentiert da auch erst zusammengewuerfelt aber voll funktionsfaehig

    BOOL CTest1Dlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    	farbe = RGB(0,0,200);
    	xstart=0;
    	ystart=150;
    	xende= 240;
    	yende=269;
    	Bild1.LoadBitmap( IDB_BITMAP1 );
    
    	// Set the icon for this dialog.  The framework does this automatically
    	// when the application's main window is not a dialog
    	SetIcon(m_hIcon, TRUE);				// Set big icon
    	SetIcon(m_hIcon, FALSE);			// Set small icon
    
    	CenterWindow(GetDesktopWindow());	// center to the hpc screen
    
    	return TRUE;  // return TRUE  unless you set the focus to a control
    }
    
    void CTest1Dlg::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    	m_VorX=point.x;
    	m_VorY=point.y;
    	//CDialog::OnLButtonDown(nFlags, point);
    	Default();
    }
    
    void CTest1Dlg::OnMouseMove(UINT nFlags, CPoint point) 
    {	
    	CClientDC cc( this );
    	if ( m_VorY> (ystart+1))
    		{
    			if((nFlags& MK_LBUTTON)==MK_LBUTTON)
    			{
    				CPen *oldpen;
    				CClientDC dc(this);
    				CPen NeuPen(PS_SOLID,2,farbe);
    				oldpen= dc.SelectObject(&NeuPen);
    
    				dc.MoveTo(m_VorX,m_VorY);
    				if ( point.y>  (ystart+1))
    				{
    					dc.LineTo(point.x,point.y);
    					m_VorX=point.x;
    					m_VorY=point.y;
    				}
    				dc.SelectObject(oldpen);
    				CDialog::OnMouseMove(nFlags, point);
    			}
    	}
    
    }
    
    void CTest1Dlg::OnExit() 
    {
    	OnOK();	
    }
    
    void CTest1Dlg::OnNeu() 
    {	
    	Invalidate();
    }
    
    void CTest1Dlg::OnPaint() 
    {	
    
    	CBrush *brush=new CBrush; 
    	brush->CreateSolidBrush(0x00FFFFFF); 
    
    	//// TRENNSTRICH ZEICHNEN ////
    	CPaintDC dc(this);
    	CPen *oldpen;
    	CPen NeuPen(PS_SOLID,2,RGB(0,0,0));
    	oldpen= dc.SelectObject(&NeuPen);
    	dc.MoveTo(0,150);
    	dc.LineTo(269,150);
    	dc.SelectObject(oldpen);
    	CDialog::OnPaint(); 
    	//////////////////////////////
    }
    void CTest1Dlg::OnNext() 
    {
    	CPaintDC pc(this);
    	//jetzt das ganze als Bitmap abspeichern 
    	CDC *dc=new CDC;				//ein neuer unabhängiger DC 
    	CBitmap *membmp=new CBitmap;	//eine Bitmap die den DC representiert 
    	RECT cr;						//für die Grösse des Clients 
    
    	dc->CreateCompatibleDC(GetDC());  
    	GetClientRect(&cr);				//Ausdehnung des Clientsbereichs ermitteln 
    	//passende Bitmap in der Grösse des Clients anlegen 
    	membmp->CreateCompatibleBitmap(GetDC(), cr.right,cr.bottom); 
    
    	//Speicherkontext mit der Bitmap verbinden 
    	dc->SelectObject(membmp); 
    	//In den Speicherkontext (eigentlich in die Bitmap!) den Inhalt des dc kopieren 
    	dc->BitBlt(0,0,cr.right,cr.bottom,GetDC(),0,0,SRCCOPY); 
    
    	//Jetzt die Bitmap speichern 
    	//WriteBitmap(_T("\\testbitmap.bmp"),membmp->operator HBITMAP(), dc->m_hDC); 
    
    	int weite = 240;
    	int hoehe = 120;
    
    	dc2bitmap(dc->m_hDC, membmp->operator HBITMAP(), _T("\\schwarzweiss.bmp"));
    
    	dc->DeleteDC(); 
    	delete dc; 
    
    	membmp->DeleteObject(); 
    	delete membmp; 
    }
    
    int CTest1Dlg::dc2bitmap(HDC hdc, HBITMAP aBmp, LPTSTR szFile2)
    {
    	int width = 240;			//Breite der zu speichernden Flaeche
    	int height = 116;			//Hoehe  der zu speichernden Flaeche
    	HDC hdc2;			
        HGDIOBJ OldObj; 
        void *dibvalues; 
        HANDLE fileHandle; 
    
        BITMAPFILEHEADER bmfh; 
    
        DWORD bytes_write; 
        DWORD bytes_written; 
    
        hdc2=CreateCompatibleDC(hdc); 
    
        DWORD sizeBI = sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD)); 
        LPBITMAPINFO lpbi = (LPBITMAPINFO) new char[sizeBI]; 
        ZeroMemory(lpbi,sizeBI); 
    
        lpbi->bmiHeader.biSize        = sizeof(BITMAPINFOHEADER); 
        lpbi->bmiHeader.biWidth       = width; 
        lpbi->bmiHeader.biHeight      = height; 
        lpbi->bmiHeader.biPlanes      = 1; 
        lpbi->bmiHeader.biBitCount    = 1; 
        lpbi->bmiHeader.biCompression = BI_RGB; 
        lpbi->bmiHeader.biSizeImage   = ((((lpbi->bmiHeader.biWidth * lpbi->bmiHeader.biBitCount) + 31) & ~31) >> 3) * lpbi->bmiHeader.biHeight; 
    
        /*for(int i = 0; i < 256; i++) 
        { 
            lpbi->bmiColors[i].rgbRed   = i; 
            lpbi->bmiColors[i].rgbGreen = i; 
            lpbi->bmiColors[i].rgbBlue  = i; 
        }*/ 
    
    	lpbi->bmiColors[1].rgbRed   = 255; 
    	lpbi->bmiColors[1].rgbGreen = 255; 
    	lpbi->bmiColors[1].rgbBlue  = 255;
    
        aBmp = CreateDIBSection(hdc,lpbi,DIB_RGB_COLORS,(void**)&dibvalues,NULL,NULL); 
    
        if (aBmp==NULL) 
        { 
            OutputDebugString(_T("CreateDIBSection failed!\n")); 
            return 0; 
        } 
    
        OldObj=SelectObject(hdc2,aBmp); 
        BitBlt(hdc2,0,0,width,height,hdc,0,150,SRCCOPY); 
    
        ZeroMemory(&bmfh,sizeof(BITMAPFILEHEADER)); 
        bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeBI; 
        bmfh.bfSize=(lpbi->bmiHeader.biHeight*lpbi->bmiHeader.biWidth)+sizeof(BITMAPFILEHEADER)+sizeBI; 
        bmfh.bfType=0x4d42; 
    
        fileHandle=CreateFile(szFile2,GENERIC_READ | GENERIC_WRITE,(DWORD)0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,(HANDLE) NULL); 
        if (fileHandle==INVALID_HANDLE_VALUE) 
        { 
            OutputDebugString(_T("WriteFile failed!\n")); 
            return 0; 
        } 
    
        // Write the BITMAPFILEHEADER 
        bytes_write=sizeof(BITMAPFILEHEADER); 
        if (!WriteFile(fileHandle,(void*)&bmfh,bytes_write,&bytes_written,NULL)) 
        { 
            OutputDebugString(_T("WriteFile failed!\n")); 
            return 0; 
        } 
    
        //Write the BITMAPINFOHEADER 
        bytes_write=sizeBI; 
        if (!WriteFile(fileHandle,(void*)lpbi,bytes_write,&bytes_written,NULL)) 
        { 
            OutputDebugString(_T("WriteFile failed!\n")); 
            return 0; 
        } 
    
        //Write the Color Index Array??? 
        bytes_write=lpbi->bmiHeader.biSizeImage;//3*bmih.biHeight*bmih.biWidth; 
        if (!WriteFile(fileHandle,(void*)dibvalues,bytes_write,&bytes_written,NULL)) 
        { 
            OutputDebugString(_T("WriteFile failed!\n")); 
            return 0; 
        } 
    
        CloseHandle(fileHandle); 
    
        DeleteObject(SelectObject(hdc2,OldObj)); 
        DeleteDC(hdc2);
    
    	return 1;
    }
    
    bool CTest1Dlg::WriteBitmap(LPTSTR szFile, HBITMAP hbitmap, HDC memdc)
    {
    	CRect rect;
    	GetClientRect(&rect);
    
    	CClientDC dc(this);
    
    	int x = 240*3;				//rect.right*3; // 24Bit pro pixel
    	int y = 120;				//rect.bottom;
    
    	char* pixel = new char[x*y];
    
    	// Pixel
    	int xpos = 0;
    	int ypos = rect.bottom;		//Upside-down format
    	int index=0;
    
    //CString test="";
    
    	while(ypos>rect.bottom-y)		//0
    	{	
    		while(xpos<(x/3))				//rect.right)
    		{
    			// Pixel auslesen und in die einzelnen Farben spalten
    			//int dummy = 0;
    
    			COLORREF col_ref = dc.GetPixel(xpos,ypos);
    
    			// Rot
    			pixel[index]=(char)(col_ref);
    			index++;
    
    			// Grün
    			pixel[index]=(char)(col_ref);
    			index++;
    
    			// Blau
    			pixel[index]=(char)(col_ref);
    			index++;
    
    			xpos++;
    
    		}
    
    		xpos=0;
    		ypos--;
    	}
    
    	BITMAPINFOHEADER infoheader;
    	infoheader.biSize=sizeof(infoheader);
    	infoheader.biWidth=(x/3);		//rect.right; //150 Breite der Bitmap
    	infoheader.biHeight=y;			//rect.bottom; //100 Höhe der Bitmap
    	infoheader.biPlanes=1;
    	infoheader.biBitCount=1;		//Farbtiefe
    	infoheader.biCompression=0;
    	infoheader.biSizeImage=0;		//Größe der Bitmap (darf 0 sein)
    	infoheader.biXPelsPerMeter=0;
    	infoheader.biYPelsPerMeter=0;
    	infoheader.biClrUsed=0;			//Alle Farben werden benützt
    	infoheader.biClrImportant=0;	//Alle Farben sind Wichtig
    
    	BITMAPFILEHEADER fileheader;
    	fileheader.bfType=19778;		//BM - Dateityp
    	fileheader.bfSize=x*y+sizeof(infoheader)+sizeof(fileheader);
    	fileheader.bfReserved1=0;
    	fileheader.bfReserved2=0;
    	fileheader.bfOffBits=(DWORD)(sizeof(fileheader)+
    	sizeof(infoheader));			//Ab hier: Pixel
    
    	// Auf Festplatte speichern
    	CFile file;
    	LPTSTR path = _T("\\bitmap.bmp");
    
    	if(!file.Open(path,CFile::modeWrite|CFile::modeCreate))
    	return false;
    
    	// Fileheader + Infoheader
    	file.Write(&fileheader,sizeof(fileheader));
    	file.Write(&infoheader,sizeof(infoheader));
    
    	// (hier: Palette für 16-256 Farben)
    
    	int nFullLength=WIDTHBYTES( infoheader.biWidth*infoheader.biBitCount );
    
    	// Pixel
    	for(int nLine=0; nLine<y; ++nLine)
    	file.Write(&pixel[nLine*x],x);
    	file.Write(&pixel[nLine*x],nFullLength-x);
    
    	file.Close();
    
    	delete[] pixel;
    	delete memdc;
    
    	return true;
    }
    

    gruss
    Guenni



  • Super, Danke. Ich werd's mir anschauen..

    LOENGLISH = LOW ENGLISH !? :p Es existieren noch weitere Map Modes, darunter auch MM_HIENGLISH. Die Map Modes definieren den Abbildungsmaßstab + Koordinatenrichtung. Bei MM_LOENGLISH entspricht eine logische Einheit 0,01 inch.

    MfG



  • und so hab ich wieder was gelernt.... 😃

    ich sehe grade dass ich noch den BITCOUNT in der 24Bit Methode auf 1 anstatt 24 habe
    koennten noch weitere kleine fehler in der 24bit methode uebrig sein da ich noch dran rumgepfuscht hatte...sorry

    gruss
    Guenni


Anmelden zum Antworten