008
29.08.2004, 15:00 Uhr
Spacelord
Hoffnungsloser Fall
|
Hi, also über SetPixel,GetPixel geht es bestimmt, aber die Performance?? Bereits bei nem Bitmap von 100*100 reden wir hier über 10000 Funktionsaufrufe,bei denen der Initialisierungscode der Funktion wahrscheinlich grösser ist als der "Sinn"(einen Pixel setzen) der Funktion. Also für Bilder nehm ich immer IPicture bzw. eine spezielle Klasse die IPicture kapselt. Mit CPictureHolder gibt es auch eine "Standardversion" die den MFC beiliegt, meine Version brauch ich nur um die Bilddaten auch aus nem binärem Stream einer DB laden zu können und weil die Methoden von CPictureHolder doch recht "dünn" sind.
Wenn ich bei der Klassenmethode Render anstatt der linken oberen Ecke meiner Zeichenfläche z.B die rechte obere Ecke angebe,dafür aber die Breite des Bildes negativ angebe spiegelt Render mir das Bild 1A.Funktioniert auch horizontal. Ich hab es zwar noch nie probiert aber ich kann mir schon vorstellen dass das bei CDC::BitBlt auch geht.
Ein ganz einfaches Beispiel das IPicture in nem Dialog direkt nutzt:
Im Header der Dialog Klasse:
C++: |
#include<afxpriv2.h> //Für CArchiveStream
.... class CBlaBlub:public CDialog { ..... public: bool LoadPicDataFromFile(); protected: IPicture* pIPic; bool ShowPicture(); ....... }
|
Ausserdem hat der Dialog ein Static Feld(IDC_BILD) dem eine Membervariable CStatic m_Bild zugeordnet ist.
In der Implementierungsdatei des Dialogs: pIPic muss im Konstruktor mit NULL initialisiert werden!!
C++: |
//Dialog .cpp
bool CBlaBlub::LoadPicDataFromFile() { CString pfad; CString filter = "JPG (*.jpg,*.jpeg,*.jpe)|*.jpg;*.jpeg;*jpe|Bitmaps (*.bmp,*.dib)|*.bmp;*.dib||"; CFileDialog* getFile = new CFileDialog(TRUE,"*.jpg",NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,filter); if((getFile->DoModal())==IDOK) { pfad = getFile->GetPathName(); delete getFile; } else { delete getFile; return false; }
CFile f; if(!f.Open(pfad,CFile::modeRead)) return false; else { CArchive ar(&f,CArchive::load|CArchive::bNoFlushOnDelete); CArchiveStream arStream(&ar); IStream* pIStr= &arStream; if(pIPic) pIPic->Release(); HRESULT hr=OleLoadPicture(pIStr,0,FALSE,IID_IPicture,(void**)&pIPic); if(hr<0) return false; } f.Close();
return true; }
bool CBlaBlub::ShowPicture() { CDC *theDC = m_Bild.GetDC(); HDC hDC = theDC->GetSafeHdc(); long hmWeite; long hmHoehe; CRect zeichenflaeche(0,0,0,0);
pIPic->get_Width(&hmWeite); pIPic->get_Height(&hmHoehe);
m_Bild.GetClientRect(&zeichenflaeche);
//normal Zeichnen pIPic->Render(hDC,zeichenflaeche.left,zeichenflaeche.top,zeichenflaeche.Width(),zeichenflaeche.Height(), 0,hmHoehe,hmWeite,-hmHoehe,NULL); /*vertikal spiegeln pIPic->Render(hDC,zeichenflaeche.right,zeichenflaeche.top,-zeichenflaeche.Width (),zeichenflaeche.Height(), 0,hmHoehe,hmWeite,-hmHoehe,NULL); */ /* horizontal spiegeln pIPic->Render(hDC,zeichenflaeche.left,zeichenflaeche.bottom,zeichenflaeche.Width(),-zeichenflaeche.Height(), 0,hmHoehe,hmWeite,-hmHoehe,NULL); */
return true; }
|
Ist halt mal wieder alles andere als objektorientiert aber das Verkapseln musst du schon selber erledigen.Es lohnt sich auf jeden Fall!! Ich hab für meine Bedürfnisse eine Klasse von CPictureHolder abgeleitet und entsprechend erweitert(Datenbankzugriff, Bilder im Originalverhältnis anzeigen usw.).Desweiteren hab ich von CStatic ne Klasse abgeleitet die ein Objekt von dieser Klasse enthält und sich ganz wunderbar und simpel wiederverwenden lässt. IPicture kann übrigens Bilder jeden Formats anzeigen,also auch jpeg,wmf und gif! Aber vorsicht mit .gif! Das Kompressionsverfahren ist patentiert und Programme die diesen Algorithmus nutzen müssen ne Lizenz haben.
MfG Spacelord -- .....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes. Dieser Post wurde am 29.08.2004 um 15:01 Uhr von Spacelord editiert. |