StretchBlt skaliert falsch



  • Ich benutze StretchBlt in der folgenden Form:

    m_pDC->StretchBlt(
    	m_rect_dest.left, // x-coord of destination upper-left corner
    	m_rect_dest.top,  // y-coord of destination upper-left corner
    	m_rect_dest.Width(), // width of destination rectangle
    	m_rect_dest.Height(), // height of destination rectangle
    	this, // handle to source DC
    	0, // x-coord of source upper-left corner
    	0, // y-coord of source upper-left corner
    	m_rect_source.Width(), // width of source rectangle
    	m_rect_source.Height(),  // height of source rectangle
    	SRCCOPY);
    

    Wenn m_rect_source kleiner ist als m_rect_dest, dann wird das Bild vergrößert, umgekehrt wird das größere Bild jedoch um den Faktor den es größer ist kleiner dargestellt, es füllt das Bild also nicht aus, sondern bei einem Unterschied von 2 nur zu einem viertel.

    Nutze ich StretchBlt in irgendeiner Weise falsch ?

    Das ganze benutze ich in einem CMemDC der folgenden Art:

    #ifndef _MEMDC_H_
    #define _MEMDC_H_
    
    class CMemDC : public CDC {
    private:	
    	CBitmap		m_bitmap;	// Offscreen bitmap
    	CBitmap*	m_oldBitmap;	// bitmap originally found in CMemDC
    	CDC*		m_pDC;		// Saves CDC passed in constructor
    	CRect		m_rect_dest;	// Rectangle of drawing area.
    	CRect		m_rect_source;  // Rectangle of source area.
    	BOOL		m_bMemDC;	// TRUE if CDC really is a Memory DC.
    public:
    
    	CMemDC(CDC* pDC, const CRect* pSourceRect = NULL, const CRect* pDestRect = NULL) : CDC()
    	{
    		ASSERT(pDC != NULL); 
    
    		// Some initialization
    		m_pDC = pDC;
    		m_oldBitmap = NULL;
    		m_bMemDC = !pDC->IsPrinting();
    
    		// Get the rectangle to draw
    		if (pDestRect == NULL) {
    			pDC->GetClipBox(&m_rect_dest);
    		} else {
    			m_rect_dest = *pDestRect;
    		}
    		// Get the rectangle to draw
    		if (pSourceRect == NULL) {
    			pDC->GetClipBox(&m_rect_source);
    		} else {
    			m_rect_source = *pSourceRect;
    		}
    
    		if (m_bMemDC) {
    			// Create a Memory DC
    			CreateCompatibleDC(pDC);
    			pDC->LPtoDP(&m_rect_dest);
    
    			m_bitmap.CreateCompatibleBitmap(pDC, m_rect_dest.Width(), m_rect_dest.Height());
    			m_oldBitmap = SelectObject(&m_bitmap);
    
    			SetMapMode(pDC->GetMapMode());
    
    			SetWindowExt(pDC->GetWindowExt());
    			SetViewportExt(pDC->GetViewportExt());
    
    			pDC->DPtoLP(&m_rect_dest);
    			SetWindowOrg(m_rect_dest.left, m_rect_dest.top);
    		} else {
    			// Make a copy of the relevent parts of the current DC for printing
    			m_bPrinting = pDC->m_bPrinting;
    			m_hDC       = pDC->m_hDC;
    			m_hAttribDC = pDC->m_hAttribDC;
    		}
    
    		// Fill background 
    		FillSolidRect(m_rect_dest, pDC->GetBkColor());
    	}
    
    	~CMemDC()	
    	{		
    		if (m_bMemDC) {
    
    			m_pDC->StretchBlt(
    				m_rect_dest.left, // x-coord of destination upper-left corner
    				m_rect_dest.top,  // y-coord of destination upper-left corner
    				m_rect_dest.Width(), // width of destination rectangle
    				m_rect_dest.Height(), // height of destination rectangle
    				this, // handle to source DC
    				0, // x-coord of source upper-left corner
    				0, // y-coord of source upper-left corner
    				m_rect_source.Width(), // width of source rectangle
    				m_rect_source.Height(),  // height of source rectangle
    				SRCCOPY);
    
    			//Swap back the original bitmap.
    			SelectObject(m_oldBitmap);		
    		} else {
    			// All we need to do is replace the DC with an illegal value,
    			// this keeps us from accidently deleting the handles associated with
    			// the CDC that was passed to the constructor.			
    			m_hDC = m_hAttribDC = NULL;
    		}	
    	}
    
    	// Allow usage as a pointer	
    	CMemDC* operator->() 
    	{
    		return this;
    	}	
    
    	// Allow usage as a pointer	
    	operator CMemDC*() 
    	{
    		return this;
    	}
    };
    
    #endif
    

    Das ganze wird aufgerufen über

    void CGraphCtrl::OnPaint() 
    {
    	CPaintDC dc(this); // device context for painting	
    
    	CRect (rc_dest);
    	rc_dest=GetSize();
    
    	CRect (rc_source);
    	rc_source=GetPlotDataSize();
    
    	CMemDC pDC(&dc,&rc_source, &rc_dest); // Double Buffering
    	PlotToDC(& pDC);
    
    }
    

    Matthias



  • Vielleicht die Frage mal anders formuliert:
    Wie skaliert man zugroße/zukleine Bilder in MFC in ein dc richtig ?

    Matthias


Anmelden zum Antworten