bitmap ausdrucken?



  • also wenn ich das richtig verstanden hab benutze ich die bitblt methode um das bitmap auszugeben (so eine art textout für bitmaps?)...
    aber was genau muss ich da als destination dc und source dc angeben? destination müsste der drucker sein, aber was ist source??

    BOOL BitBlt(
      HDC hdcDest, // handle to destination DC
      int nXDest,  // x-coord of destination upper-left corner
      int nYDest,  // y-coord of destination upper-left corner
      int nWidth,  // width of destination rectangle
      int nHeight, // height of destination rectangle
      HDC hdcSrc,  // handle to source DC
      int nXSrc,   // x-coordinate of source upper-left corner
      int nYSrc,   // y-coordinate of source upper-left corner
      DWORD dwRop  // raster operation code
    );
    

    meine aktuelle methode um dieses bitmap auszudrucken sieht im moment so aus (bei den formalen parametern im methodenkopf, das was hier überflüssig ist brauch ich nachher noch für text)...
    ich bin mir nicht so ganz sicher was ich mit hInstance anfangen soll... was genau ist das?

    void PageGDICalls(HDC hdcPrn,int cxPage,int cyPage) 
    { 
    	HINSTANCE hInstance;
    
    	HDC hdcMem = CreateCompatibleDC (hdcPrn);
        HBITMAP hBitmap = (HBITMAP)LoadImage(hInstance,"C:\\Dokumente und Einstellungen\\Administrator\\Desktop\\icann-logo.bmp",IMAGE_BITMAP,NULL,NULL,LR_DEFAULTSIZE|LR_LOADFROMFILE);
    
    	BitBlt(
    		hdcPrn, // handle to destination DC
    		0,		// x-coord of destination upper-left corner
    		0,		// y-coord of destination upper-left corner
    		188,	// width of destination rectangle
    		145,	// height of destination rectangle
    		hdcPrn, // handle to source DC
    		0,		// x-coordinate of source upper-left corner
    		0,		// y-coordinate of source upper-left corner
    		SRCCOPY // raster operation code
    	);
    
     SelectObject (hdcMem,hBitmap);
    
    	SaveDC(hdcPrn);
    
    }//end PageGDICalls
    

    is das so in etwa ok oder hab ich wieder seltsame leichtsinnsfehler gemacht? 😃



  • Du musst das Bitmap in einen Memory-DC selektieren - das ist dann der Source-DC
    Also das SelectObject (hdcMem,hBitmap); vor den BitBlt-Aufruf und dann hdcMem als Source-DC angeben 😉



  • moon schrieb:

    ich bin mir nicht so ganz sicher was ich mit hInstance anfangen soll... was genau ist das?

    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
    

    Fällt Dir da was auf?
    hInstance ist eine Art "Programmzähler", der von Windows erhöht wird, sobald Dein Programm gestartet wird. Es "identifiziert" quasi Dein Programm...

    Wenn Du nun bei LoadImage als ersten Parameter hInstance angibst und z. B. ein Bitmap aus einer Resource DEINES Programmes laden willst, "sagst" Du Windows quasi, das die Resource in DEINEM Programm steckt...

    Deshalb legt man sich für gewöhnlich eine globale HINSTANCE-Variable an, damit man jederzeit drauf zugreifen kann.

    Beispiel:

    #include <windows.h>
    
    HINSTANCE MyInstance;
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
    {
        MyInstance = hInstance;
        ...
    }
    

    Du kannst aber die HINSTANCE Deines Programmes jederzeit mit

    MyInstance = (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE);
    

    erfahren. Dazu allerdings brauchst Du einen HWND auf Dein Fenster...

    In Deinem Beispiel ist der Wert von hInstance nahezu egal, da Du das Bitmap eh von der Festplatte lädst...



  • @flenders:
    ein memory dc erzeuge ich durch CreateCompatibleDC. dann lade ich das bitmap aus einer datei und selektiere mit SelectObject das bitmap ins memory dc. danach führe ich BitBlt mit hdcMem als source und hdcPrn als destination aus, richtig?

    aber dann müsste es doch so stimmen? läuft leider nicht. ich bekomme bloß ein leeres blatt ausgedruckt.

    HDC hdcMem = CreateCompatibleDC (hdcPrn);
        HBITMAP hBitmap = (HBITMAP)LoadImage(hInstance,"C:\\Dokumente und Einstellungen\\Administrator\\Desktop\\icann-logo.bmp",IMAGE_BITMAP,NULL,NULL,LR_DEFAULTSIZE|LR_LOADFROMFILE);
    
    	SelectObject (hdcMem,hBitmap);
    
    	BitBlt(
    		hdcPrn, // handle to destination DC
    		0,		// x-coord of destination upper-left corner
    		0,		// y-coord of destination upper-left corner
    		188,	// width of destination rectangle
    		145,	// height of destination rectangle
    		hdcMem, // handle to source DC
    		0,		// x-coordinate of source upper-left corner
    		0,		// y-coordinate of source upper-left corner
    		SRCCOPY // raster operation code
    	);
    


  • hInstance: Handle to an instance of the module that contains the image to be loaded (steht für LoadImage() in der PSDK-Doku)
    Da du aber das Bild gar nicht aus den Resourcen deines Programms lädst, musst Du da statt hInstance einfach NULL schreiben!

    LR_DEFAULTSIZE
    Uses the width or height specified by the system metric values for cursors or icons, if the cxDesired or cyDesired values are set to zero. If this flag is not specified and cxDesired and cyDesired are set to zero, the function uses the actual resource size. If the resource contains multiple images, the function uses the size of the first image

    Das heisst, du kannst und solltest LR_DEFAULTSIZE weglassen 😃

    Und prüf mal den Rückgabewert:

    HBITMAP bmp;
    bmp=(HBITMAP)LoadImage(NULL,"c:\\pfad\\bla.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    if (bmp)
    {
       OutputDebugString("Bitmap erfolgreich geladen!\n");
    }
    else
    {
       OutputDebugString("Fehler!!\n");
    }
    


  • habe geekys rat befolgt, die änderungen gemacht und den test mal durchgeführt. das bitmap wird richtig geladen... das ist also nicht der fehler (denk ich)... leider ist das ergebnis immer noch eine schneeweiße seite...
    am besten poste ich hier nochmal meinen gesamten code hin...
    immer her mit den tipps, ihr seid die besten 😃 und ich weiß, ich bin ein schwerer fall 🙄

    #include <windows.h> 
    HINSTANCE hInstance; 
    
    //****************************************************************************** 
    //Gerätekontext ermitteln
    
    HDC GetPrinterDC(void) 
    { 
        DWORD                dwNeeded, dwReturned; 
        HDC                  hdc; 
        PRINTER_INFO_4       * pinfo4; 
    
    	//Aufzählungsfunktion um angeschlossene Drucker zu erfassen
    	//EnumPrinters(Druckerobjekt-Typ, Name des Druckers, Informationslevel, Druckerinformation Buffer, Größe des Druckerinformation Buffer, erhaltene oder benötigte Bytes, Anzahl der gezählten Drucker);
    
        EnumPrinters(PRINTER_ENUM_LOCAL,NULL,4,NULL,0,&dwNeeded,&dwReturned); 
        pinfo4=(PRINTER_INFO_4*)malloc(dwNeeded); 
        EnumPrinters(PRINTER_ENUM_LOCAL,NULL,4,(PBYTE)pinfo4,dwNeeded,&dwNeeded,&dwReturned); 
    
    	//Gerätekontext anlegen
    	//hdc=CreateDC(Name des Treibers, Name des Druckers, ignorieren-immer NULL, Initialisierungsdaten-meist NULL);
        hdc=CreateDC(NULL,pinfo4->pPrinterName,NULL,NULL);			
        free(pinfo4); 
    
        return hdc; 
    } //end GetPrinterDC
    
    //******************************************************************************  
    //Ausgabe
    //Handle des Druckerkontext + Höhe + Breite der Seite werden übergeben
    
    void PageGDICalls(HDC hdcPrn,int cxPage,int cyPage) 
    { 
    
    	HDC hdcMem = CreateCompatibleDC (hdcPrn);
        HBITMAP hBitmap = (HBITMAP)LoadImage(NULL,"C:\\Dokumente und Einstellungen\\Administrator\\Desktop\\icann-logo.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    
    	SelectObject (hdcMem,hBitmap);
    
    	BitBlt(
    		hdcPrn, // handle to destination DC
    		0,		// x-coord of destination upper-left corner
    		0,		// y-coord of destination upper-left corner
    		188,	// width of destination rectangle
    		145,	// height of destination rectangle
    		hdcMem, // handle to source DC
    		0,		// x-coordinate of source upper-left corner
    		0,		// y-coordinate of source upper-left corner
    		SRCCOPY // raster operation code
    	);
    
    	SaveDC(hdcPrn);
    
    }//end PageGDICalls
    
    //****************************************************************************** 
    //main
    
    void main() 
    { 
    	HDC GetPrinterDC(void); 
    	void PageGDICalls(HDC,int,int); 
    
    	//eigentlicher Druckauftrag
    
    	//DOCINFO di={Strukturgröße in Byte, Name des auszudruckenden Dokuments/wird in der Drucker-Wartschlange angezeigt)
    	static	DOCINFO di={sizeof(DOCINFO),TEXT("GreenCode druckt")}; 
        BOOL	bSuccess=TRUE; 
        HDC		hdcPrn; 
        int		xPage,yPage; 
    
        if(NULL==(hdcPrn=GetPrinterDC())) 
            bSuccess=FALSE; 
    
    	//Höhe und Breite der Druckseite ermitteln (nicht physikalisch, sondern druckbare Zeichenfläche)
        xPage=GetDeviceCaps(hdcPrn,HORZRES); 
        yPage=GetDeviceCaps(hdcPrn,VERTRES); 
    
    	//wenn StartDoc einen positiven Wert liefert (dh. alles ok) wird StartPage aufgerufen
        if(StartDoc(hdcPrn,&di)>0) 
        { 
    		//neue Seite
            if(StartPage(hdcPrn)>0) 
            { 
                PageGDICalls(hdcPrn,xPage,yPage); 
    
                if(EndPage(hdcPrn)>0) 
                        EndDoc(hdcPrn); 
                else 
                    bSuccess=FALSE; 
            } 
        } 
        else 
            bSuccess=FALSE; 
    
        DeleteDC(hdcPrn); 
    
    }//end main
    


  • Ich habe es bei mir gerade mal auspobiert und festgestellt, dass es funktioniert, wenn du CreateCompatibleDC NULL übergibst (anstatt hdcPrn). Außerdem wirst du wohl StrechBlt brauchen, da das Bild sonst winzig klein gedruckt wird 🙂



  • juhuuu, es läuft 🙂 he jungs, zur feier des tages geb ich ne runde aus, was haltet ihr davon 😃



  • Ich bin strikter Anti-Alkoholiker, aber eine große Apfelschorle würd ich schon nehmen 😉



  • Hi Leute ich versuche verzweifelt, das Drucken von Bildern auch hinzubekommen....

    Bei mir fukntioniert es aber einfach nicht!

    void CADS2Dlg::Logos(CDC* dcPrint)
    {
    HDC hdcMem = CreateCompatibleDC (NULL); 
        HBITMAP hBitmap = (HBITMAP)LoadImage(NULL,"E:\\test.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); 
    
        SelectObject (hdcMem,hBitmap); 
    
        BitBlt( 
            hdcMem, // handle to destination DC 
            0,        // x-coord of destination upper-left corner 
            0,        // y-coord of destination upper-left corner 
            188,    // width of destination rectangle 
            145,    // height of destination rectangle 
            hdcMem, // handle to source DC 
            0,        // x-coordinate of source upper-left corner 
            0,        // y-coordinate of source upper-left corner 
            SRCCOPY // raster operation code 
        ); 
    
        SaveDC(hdcMem); 
    
    }
    

    Mein Problem ist, dass ich ein CDC-Obejkt habe....
    Wie kann ich dann den Code auf meine Druckmethode anpassen?
    z.B Text drucke ich so:

    dcPrint->DrawText(...);
    

    Wie kann ich den so Bilder drucken?



  • Dann scheinst du wohl MFC zu verwenden (dafür gibt es ein extra Forum). Ansonsten denke ich, dass du eben bei allen Funktionen, denen hdcMem im ersten Parameter übergeben wird, diese stattdessen über dcPrint-> aufrufst und diesen ersten Parameter weglässt 🙂

    Das war jetzt aber alles nur eine Vermutung - ansonsten solltest du im MFC-Forum mal nachfragen 🕶



  • Hi,
    wie genau ist das gemeint, bzw wo muss man den Sourcecode so abändern das es funktioniert?

    flenders schrieb:

    Ich habe es bei mir gerade mal auspobiert und festgestellt, dass es funktioniert, wenn du CreateCompatibleDC NULL übergibst (anstatt hdcPrn). Außerdem wirst du wohl StrechBlt brauchen, da das Bild sonst winzig klein gedruckt wird 🙂

    Schonmal THX
    Nys


Anmelden zum Antworten