Grafik ausdrucken



  • Hallo.

    Ich habe jetzt schon gut 30Seiten gedruckt und bekomme es nicht so hin wie gern hätte und bevor ich hier noch meine Tintenpatrone gänzlich leer mache mein Hilfegesuch hier 🤡

    Ich habe eine Grafik, mal Hochformat und mal Horizontalformat ausdrucken.
    Ich möchte diese Grafiken auf das Blatt ausdrucken und zwar so das es das Blatt ausfüllt ABER den Rand beachtet den ich in 4 Eingabefeldern eingetragen habe.
    In den 4 Eingabefeldern gebe ich in Millimeter (Integer) den Rand ein für alle vier Seiten.

    Ich glaube das man den Rand drehen muss wenn man Landscape(Horizontal) nutzt.
    Normal steht
    TeSEdit1 = links
    TeSEdit2 = rechts
    TeSEdit3 = oben
    TeSEdit4 = unten

    TeSEdit5(Breite) und TeSEdit6(Höhe) sind ein zusätzlicher Streckfaktor, falls man es doch kleiner/grösser haben will.

    int rand_l,rand_r,rand_o,rand_u;
    
        if (prnt_orientation==Portrait)
        {
            Prntr->Orientation = poPortrait;
            // in Millimeter
            rand_l = StrToInt(TeSEdit1->Text);
            rand_r = StrToInt(TeSEdit2->Text);
            rand_o = StrToInt(TeSEdit3->Text);
            rand_u = StrToInt(TeSEdit4->Text);
        }
        else
        {
            Prntr->Orientation = poLandscape;
            // in Millimeter
            rand_l = StrToInt(TeSEdit3->Text);
            rand_r = StrToInt(TeSEdit4->Text);
            rand_o = StrToInt(TeSEdit2->Text);
            rand_u = StrToInt(TeSEdit1->Text);
        }
    
        int width = GetDeviceCaps(Prntr->Handle, LOGPIXELSX);
        int height = GetDeviceCaps(Prntr->Handle, LOGPIXELSY);
    
        int ScaleX = GetDeviceCaps(Prntr->Handle, LOGPIXELSX) / PixelsPerInch;
        int ScaleY = GetDeviceCaps(Prntr->Handle, LOGPIXELSY) / PixelsPerInch;
    
        // 1 inch = 2.54 cm = 25.4 mm
      	float papermmx = GetDeviceCaps(Prntr->Canvas->Handle, PHYSICALWIDTH) /
        							   GetDeviceCaps(Prntr->Canvas->Handle, LOGPIXELSX) * 25.4;
      	float papermmy = GetDeviceCaps(Prntr->Canvas->Handle, PHYSICALHEIGHT) /
    								   GetDeviceCaps(Prntr->Canvas->Handle, LOGPIXELSY) * 25.4;
    
        int new_paper_width = papermmx - rand_l - rand_r;
        int new_paper_height = papermmy - rand_o - rand_u;
    
        int new_width = image->Width * new_paper_width / papermmx;
        int new_height = image->Height * new_paper_height / papermmy;
    
        TRect rect;
        rect.Left = Prntr->PageWidth * rand_l / papermmx;
        rect.Right = rect.Left + ((image->Width * ScaleX) + ((image->Width * ScaleX) * StrToInt(TeSEdit5->Text) / 100));
        rect.Top = Prntr->PageHeight * rand_o / papermmy;
        rect.Bottom = rect.Top + ((image->Height * ScaleY) + ((image->Height * ScaleY) * StrToInt(TeSEdit6->Text) / 100));
    /*
        rect.Left = new_width * rand_l / papermmx;
        rect.Right = rect.Left + ((new_width * ScaleX) + ((new_width * ScaleX) * StrToInt(TeSEdit5->Text) / 100));
        rect.Top = new_height * rand_o / papermmy;
        rect.Bottom = rect.Top + ((new_height * ScaleY) + ((new_height * ScaleY) * StrToInt(TeSEdit6->Text) / 100));
    */
        Prntr->Canvas->StretchDraw(rect, image->Picture->Bitmap);
    

    Falls hier jemand helfen kann ... boah wäer so klasse 🙄



  • Hi,

    Wenn du uns denn verrätst wo der Fehler is ;-)... bzw. was dein Problem ist?! Skaliert er nicht richtig, druckt er gar nich, kocht er plötzlich kaffee?!?!

    mfg, Micha



  • Oh. Nunja er druckt es schon, aber eben nicht so auf das Blatt wie ich es gern hätte.

    Weder stimmt der Rand, noch benutzt er den möglichen freien Platz.
    Er druckt die Grafik irgendwie aufs Papier.

    Beim drucken ist zu beachten das der Ratio der Grafik beibehalten werde muss.
    Ich meine damit das wenn Grafik 700x300Pixel sind und jetzt mal übertragen auf dem Blatt Papier 1000x600 Pixel zur Verfügung ständen nicht diese so simple benutzt, da dann ja das Bild verzerrt gedruckt würde.

    Naja ich spiel mal weiter rum 🕶



  • Ich habe mir nen leeres Projekt gemacht mit 1 Button, 6 Edits und 1 Image

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        TImage *image = Image1;
        int prnt_orientation = Portrait;
    
    	TPrinter *Prntr = Printer();
    
        // in Millimeter
        int rand_l,rand_r,rand_o,rand_u;
    
        if (prnt_orientation==Portrait)
        {
            Prntr->Orientation = poPortrait;
            // in Millimeter
            rand_l = StrToInt(Edit1->Text);
            rand_r = StrToInt(Edit2->Text);
            rand_o = StrToInt(Edit3->Text);
            rand_u = StrToInt(Edit4->Text);
        }
        else
        {
            Prntr->Orientation = poLandscape;
            // in Millimeter
            rand_l = StrToInt(Edit3->Text);
            rand_r = StrToInt(Edit4->Text);
            rand_o = StrToInt(Edit2->Text);
            rand_u = StrToInt(Edit1->Text);
        }
    
    	Prntr->BeginDoc();
        //Prntr->Title = "";
    
        int width = GetDeviceCaps(Prntr->Handle, LOGPIXELSX);
        int height = GetDeviceCaps(Prntr->Handle, LOGPIXELSY);
        Memo1->Lines->Add("width: "+IntToStr(width));
        Memo1->Lines->Add("height: "+IntToStr(height));
    
        int ScaleX = GetDeviceCaps(Prntr->Handle, LOGPIXELSX) / PixelsPerInch;
        int ScaleY = GetDeviceCaps(Prntr->Handle, LOGPIXELSY) / PixelsPerInch;
        Memo1->Lines->Add("ScaleX: "+IntToStr(ScaleX));
        Memo1->Lines->Add("ScaleY: "+IntToStr(ScaleY));
    
        // 1 inch = 2.54 cm = 25.4 mm
      	float papermmx = GetDeviceCaps(Prntr->Canvas->Handle, PHYSICALWIDTH) /
        							   GetDeviceCaps(Prntr->Canvas->Handle, LOGPIXELSX) * 25.4;
      	float papermmy = GetDeviceCaps(Prntr->Canvas->Handle, PHYSICALHEIGHT) /
    								   GetDeviceCaps(Prntr->Canvas->Handle, LOGPIXELSY) * 25.4;
        Memo1->Lines->Add("papermmx: "+FloatToStr(papermmx));
        Memo1->Lines->Add("papermmy: "+FloatToStr(papermmx));
    
        int new_paper_width = papermmx - rand_l - rand_r;
        int new_paper_height = papermmy - rand_o - rand_u;
        Memo1->Lines->Add("new_paper_width: "+IntToStr(new_paper_width));
        Memo1->Lines->Add("new_paper_height: "+IntToStr(new_paper_height));
    
        int new_width = image->Width * new_paper_width / papermmx;
        int new_height = image->Height * new_paper_height / papermmy;
        Memo1->Lines->Add("new_width: "+IntToStr(new_width));
        Memo1->Lines->Add("new_height: "+IntToStr(new_height));
    
        TRect rect;
        rect.Left = Prntr->PageWidth * rand_l / papermmx;
        rect.Right = rect.Left + ((image->Width * ScaleX) + ((image->Width * ScaleX) * StrToInt(Edit5->Text) / 100));
        rect.Top = Prntr->PageHeight * rand_o / papermmy;
        rect.Bottom = rect.Top + ((image->Height * ScaleY) + ((image->Height * ScaleY) * StrToInt(Edit6->Text) / 100));
        Memo1->Lines->Add("Left: "+IntToStr(rect.Left));
        Memo1->Lines->Add("Right: "+IntToStr(rect.Right));
        Memo1->Lines->Add("Top: "+IntToStr(rect.Top));
        Memo1->Lines->Add("Bottom: "+IntToStr(rect.Bottom));
    
        //Prntr->Canvas->StretchDraw(rect, image->Picture->Bitmap);
    
    	Prntr->EndDoc();
    }
    

    Memo Ausgabe ist

    width: 600
    height: 600
    ScaleX: 6
    ScaleY: 6
    papermmx: 203,199996948242
    papermmy: 203,199996948242
    new_paper_width: 153
    new_paper_height: 249
    new_width: 180
    new_height: 285
    Left: 468
    Right: 1908
    Top: 243
    Bottom: 2163

    Die Grafik ist 240(breit)x320(hoch)

    Warum ist das erste width udn height 600?
    LOGPIXELSX Number of pixels per logical inch along the screen width.
    LOGPIXELSY Number of pixels per logical inch along the screen height.
    Das kann doch schonmal garnicht das gleiche sein?! 😮

    Rand Eingabe war links=30, oben und unten=20 und rechts=10
    Grafik auf Papier ist links=25mm und oben=15mm. Grafik ist auf dem Blatt 60mm breit und so 81mm hoch.

    Per Haken(CheckBox) möchte ich dann FitToPage einstellen, wo es dann 170mm breit werden müsste und nach Rechnung 227mm hoch werden sollte (320*170/240).



  • Ich hab hier mal ne Funktion aus einem meiner Projekte rausgekramt:

    if (PrintDialog1->Execute())
    	{
    		int CurPrinter;
    		PrintDialog1->Name;
    		TPrinter*	prn = Printer();
    
    		if (bmp_rotate % 2 && prn->Orientation == poPortrait)
    			prn->Orientation = poLandscape;
    		else
    			prn->Orientation = poPortrait;
    
    		TRect PrinterRect;
    		PrinterRect = Rect(0,0,prn->PageWidth, prn->PageHeight);
    		double x, y;
    		x = (double) PrinterRect.Right / (double) BitmapShow->Width;
    		y = (double) PrinterRect.Bottom / (double) BitmapShow->Height;
    		if (x != y)
    			PrinterRect.Bottom = (PrinterRect.Bottom / y) * x;
    		if (ComboBox1->Visible)
    			prn->Title = ExtractFileName(slFiles->Strings[ComboBox1->ItemIndex]);
    		else
    			prn->Title = ExtractFileName(slFiles->Strings[0]);
    		prn->BeginDoc();
    		prn->Canvas->StretchDraw(PrinterRect, BitmapShow);
    		prn->EndDoc();
    		prn->Orientation = poPortrait;
    	}
    

    Wobei BitmapShow das zu druckende bmp ist. Die Ausrichtung wird hier bereits in der Varibable bmp_rotate vorgegeben, die bereits in der Grafikausgabe auf den Monitor ermittelt wird. Dabei wird auch das Bitmap in BitmapShow bereits in die richtige Lage gedreht. Drehen brauchst Du aber eigentlich nicht, da Du einfach nur prüfen mußt, ob die Bitmap breiter als hoch ist und wenn ja, die Orientation auf Landscape setzen mußt.



  • Danke für deinen Code, ich habe diesen mal sofort ausprobiert. Er druckt im korrekten Verhältnis meine Grafik 240x320=0.75 => 200x267=0.749 mit einem Seitenrand von 5mm.

    Mein Problem ist nun:

    A) Ich möchte den Rand(links,oben,rechts,unten) den er mindestens selbst einhalten soll selbst gern festlegen können.
    Alles was ich bisher probierte führte aber zu keinem korrekten Ergebnis 😞

    😎 Der Ausdruck soll (A einbezogen) dann Originalgrösse auf Papier haben, wobei man mit zwei Prozent-werten manuell Breite und Höhe nachstrecken kann.

    C) Wie in deinem Beispiel, soll die Grafik FitToPage auf die ganze Seite, jedoch mit beachten meines festgelegten Randes(siehe A)

    Ich such mich schon durch diverse Tutorials, leider bisher ohne es umzusetzen wissen. *stöhn* Wäre super wenn jemand das gleiche Problem schonmal hatte und bei Lösung helfen könnte. 👍



  • Lösung wäre schon wenn ich wüsste wie ich aus meiner Image Breite statt Pixel es in Millimeter bekommen kann. Aber wie?

    Wie bekomme ich raus wieviel 320Pixel in Millimeter sind?

    Prntr->BeginDoc();
    
    //Umstellen auf 1/10 mm
    SetMapMode(Prntr->Canvas->Handle, MM_LOMETRIC);
    
    //Blattgröße in 1/10 mm ermitteln:
    int breite = GetDeviceCaps(Prntr->Canvas->Handle, HORZSIZE) * 10;
    int hoehe = GetDeviceCaps(Prntr->Canvas->Handle, VERTSIZE) * 10;
    

    So habe ich das Papier auf Millimeter und kenne dessen Milliemeter Breite(2020) und Höhe(2880)

    Das sagt mir auch schoneinmal das nicht das ganze Blatt genommen wird, da wenn ich Lineal anlege es 21cm breit und 29.8cm hoch ist.

    Ein Rand von 30mm (3cm) ist dann wenn ich nachmesse also nicht 3cm vom Blattrand entfernt?

    Wenn ich

    GetDeviceCaps(Image1->Canvas->Handle, HORZSIZE) * 10;
    

    Dann erhalte ich 3200, was ja nicht stimmen kann 😉



  • um einen Rand festzulegen mußt du eigentlich nur das Rect anpassen, im Beispiel von Joe_M. wär das:

    int Border = 50; //Angabe in Pixel;
    //int Border = Prn->PageWidth*15/GetDeviceCaps(Prn->Canvas->Handle, HORZSIZE); 
    PrinterRect = Rect(Border,Border,prn->PageWidth-Border, prn->PageHeight-Border);
    


  • Also FitToPage habe ich so gelöst

    Prntr->BeginDoc();
        SetMapMode(Prntr->Canvas->Handle, MM_LOMETRIC);  //Umstellen auf 1/10 mm
    
        //Blattgröße in 1/10 mm ermitteln:
        int breite = GetDeviceCaps(Prntr->Canvas->Handle, HORZSIZE) * 10;
        int hoehe = GetDeviceCaps(Prntr->Canvas->Handle, VERTSIZE) * 10;
    
        // Rand
        int randL = 300;
        int randR = 100;
        int randO = 200;
        int randU = 200;
    
        // FitToPage
        int bwidth = breite - randL - randR;
        int bheight = image->Height * bwidth / image->Width + randO;
    
        // Achtung: Grafik würde zu hoch werden, muss nach Höhe berechnet werden
        if (bheight>hoehe-randU)
        {
            bheight = hoehe - randO - randU;
            bwidth = image->Width * bheight / image->Height + randL;
        }
    
        TRect PrinterRect = Rect(randL, -randO, randL + bwidth, -bheight);
        Prntr->Canvas->StretchDraw(PrinterRect, image);
    
        Prntr->EndDoc();
    

    Klappt auch, mein Problem jetzt ist aber noch die Originalgrösse mit möglichem Stretchfaktor. 😞
    Dazu müsste ich wissen wieviel Millimeter meine 240Pixel Breite sind. Kann wer sagen wie ich auf diesen Wert komme?



  • Bei 600 dpi

    Formel: Größe in cm * 600 dpi / 2,54 = Maß in Pixel;
    Maß in Pixel * 2,54 / 600 dpi = Größe in cm

    Das Problem dürfte sein, herauszufinden, mir wieviel dpi das Bild gespeichert wurde.



  • Mein Problem ist, das wenn ich die Grafik ausdrucke, manches (sehr kleine Texte 6Pixel hoch) verschwommen ist, wie zum Bespiel eine "8", welche als solches nicht erkennbar mehr ist. Wenn ich das Bitmap in Grafiktool lade und ausdrucke macht er es aufs ganze Bild und kann man lesen.


Anmelden zum Antworten