printer.XDPI – YDPI

Verweis: PageWidth..PageHeight
Uses: Printers
Eingabe: Nichts
Ausgabe: Druckpunkte(Integer)
Funktion: Die Methoden geben die Anzahl der Druckpunkte je Inch an.

Beispiel 1

Bereiten Sie eine neue IDE Anwendung wie in dieser Anleitung printer4lazarus-installation gezeigt, vor. Zusätzlich benötigen Sie noch Folgende Komponenten:
TButton

function RectToStr(sR: TRect; Absolut: boolean = False): string;
begin
  if Absolut then
    Result := Format('X1= %d, Y1= %d, X2= %d, Y2= %d',
      [sR.Left, sR.Top, sR.Left + sR.Width, sR.Top + sR.Height])
  else
    Result := Format('X= %d, Y= %d, L= %d, H= %d',
      [sR.Left, sR.Top, sR.Width, sR.Height]);
end;



procedure TForm1.Button1Click(Sender: TObject);
const
  Faktor300dpi = 1.181102362204724;
var
  Papierpunkte, Druckpunkte: TRect;
  ZeichenMap: TBitmap;
  MapX, MapY, f: integer;
begin
  ;
  printer.Orientation := poPortrait;
  Papierpunkte := printer.PaperSize.PaperRect.PhysicalRect;
  Druckpunkte := printer.PaperSize.PaperRect.WorkRect;
  ShowMessage('Arbeitsbereich Größe: ' + RectToStr(
    Druckpunkte) + #13#10 + 'Physikalische Größe:   ' +
    RectToStr(Papierpunkte) + #13#10 +
    'Auflösung Bildpunkte pro inch (25,4mm): ' +
    IntToStr(printer.XDPI) + ' DPI');
  //Erstelle Zeichen map
  ZeichenMap := TBitmap.Create;

  //A4 Maße in mm 210 x 297 bei 300 dpi 2480 x 3508
  if printer.XDPI = 300 then
  begin
    MapX := Round(Papierpunkte.Width / Faktor300dpi);
    MapY := Round(Papierpunkte.Height / Faktor300dpi);
    //Setze Größe
    ZeichenMap.SetSize(MapX, MapY);
  end;
  //A4 Maße in mm 210 x 297 bei 600 dpi 4960 x 7016
  if printer.XDPI = 600 then
  begin
    MapX := Round(Papierpunkte.Width / (Faktor300dpi * 2));
    MapY := Round(Papierpunkte.Height / (Faktor300dpi * 2));
    ZeichenMap.SetSize(MapX, MapY);
  end;
  ZeichenMap.Canvas.Brush.Style := bsSolid;
  ZeichenMap.Canvas.Brush.Color := clWhite;
  ZeichenMap.Canvas.FillRect(1, 1, MapX - 1, MapY - 1);
  //Jetzt Zeichnen wir auf die ZeichenMap
  with Zeichenmap do
  begin
    canvas.Pen.Color := clBlack;
    canvas.Pen.Width := 2;
    Canvas.Font.Size := 30;
    for f := 1 to 20 do
    begin
      Canvas.Line(100 * f, 100, 100 * f, 200);
      Canvas.TextOut(100 * f - 20, 10, IntToStr(f));
    end;
  end;
  Printer.beginDoc;
  Printer.Canvas.StretchDraw(Rect(0, 0, Printer.PageWidth,
    Printer.PageHeight), ZeichenMap);
  Printer.EndDoc;
  ZeichenMap.Free;
end;

In dem Beispiel definieren wir eine Konstante die aus 300/254 berechnet wird. Hiermit habe ich einen Faktor wenn ich den jetzt auf 300 Punkte anwende bekomme ich 254 heraus, dies ist der Wert für die Drucklänge in 1/10 mm was Sinn macht. Dies Gilt aber nur für 300 DPI wenn sich die Auflösung verdoppelt muss sich auch der Faktor verdoppeln da das, gleiche Papier die doppelten Punkte in der Länge haben. Nachdem wir in dem Beispiel mit dem Befehl:

  printer.Orientation := poPortrait;

Das Blatt in Hochformat geschaltet. Damit dann ein kleines Info Fenster angezeigt werden kann. Dieses Fenster sieht dann ungefähr so aus wie dieses:

Lazarus Auflösung anzeigen.
Hier ist die Auflösung 300 DPI

Hier sehen sie den Arbeitsbereich bei einer Auflösung von 300 DPI bei einem angewähltem DIN A4 Blatt. Wenn Sie das Beispiel benutzen möchten, sollten Sie die Auflösung in der Systemsteuerung für Ihren Drucker auf 300- oder 600 DPI stellen. Wir könnten hier auch eine Formel benutzen die mehr Auflösungen errechnen kann. Dies würde aber auf Kosten der Übersichtlichkeit und des Lehrneffektes gehen. In dem nächsten Abschnitt, basteln wir uns ein Lineal. Dies fängt bei 1 an und hört bei 20 auf. Dies realisieren wir mit einer Schleife. Die Zahl 100 ergibt auf dem Papier Abstände von einem 1 cm.

Lazarus Linieal mit XDPI berechnet.
Das Ergebnis unseres Programms.

Das Ergebnis sieht, auf den ersten Blick, ganz nett aus. Aber nur auf den ersten Blick. Halten wir doch mal die Lupe drauf.

Lazarus Bitmap
Die 3 Vergößert

Huch, ganz pixelig. Zum Einen entsteht dies durch die Skalierung zum Andern durch die Umwandlung in eine Bitmap.

Die Skalierung

Stellen wir uns folgendes vor. Sie haben eine Bitmap von 900 Bildpunkten. Wenn wir nun hier eine Linie bei 300 Punkten mit einer Linien-Breite von 1 Pixel zeichnen und im nach hinein auf 300 Punkten verkleinern, dann hat das Programm doch ein Problem. Die Linie kann noch gut an der Position von (300 durch 3) also bei 100 Punkten gezeichnet werden. Nur was macht das Programm jetzt mit der 1 Pixel dicken Linie. 1 durch 3 sind 0,3 , wenn wir diesen Wert runden, weil nur ganze Zahlen zulässig sind, dann haben wir 0. Null bedeutet in diesem Fall die Linie ist weg. Das Blatt bleibt weiß. Als Kompromiss wird nun die Linie mit einer Breite von einem Pixel gezeichnet aber nur noch mit einem Drittel von der schwarzen Farbe. Und genau das macht die Methode “Canvas.StretchDraw”.

Vektor vs BitMap

Was sich jedoch besonders auswirkt, ist die Tatsache, dass wir auf eine BitMap Gezeichnet haben. Das Prtinter.Canvas ist keine BitMap im eigentlichen Sinne. Es ist eine Zeichenfläche, die bei der Ausgabe eher an ein Integer Array in einem Koordinatensystem erinnert als an eine Bitmap. Was das bedeutet, schauen wir uns hier an.

Beispiel 2

Bereiten Sie eine neue IDE Anwendung wie in dieser Anleitung printer4lazarus-installation gezeigt, vor. Zusätzlich benötigen Sie noch Folgende Komponenten:
TButton

procedure TForm1.Button1Click(Sender: TObject);
Var
  f:Integer;
begin
  printer.Orientation := poPortrait;
  Printer.beginDoc;
  with Printer do
  begin
    canvas.Pen.Color := clBlack;
    canvas.Pen.Width := 1;
    Canvas.Font.Size := 20;
    for f := 1 to 20 do
    begin
      Canvas.Line(118 * f, 100, 118 * f, 200);
      Canvas.TextOut(118 * f - 20, 10, IntToStr(f));
    end;
  end;
  Printer.EndDoc;
end;

Bitte achten Sie in dem Beispiel bitte darauf, dass sie ein DIN – A4 – Blatt angewählt haben und dies mit einer Auflösung von 300 DPI bedrucken wollen. Denn das Beispiel, welches hier stark abgespeckt ist, achtet nun nicht mehr auf die Auflösung. Hier Drucken wir auch direkt auf das Canvas des Printers.

Lazarus Vektor - Bitmap
Vektor versus Bitmap

Bei Text und CAD – Programmen ist die Vektorgrafik vorzuziehen. Fotos und Filme liegen von von vornherein als BitMap vor. Wenn Sie Text oder Tabellen oder Zeichnungen ausdrucken wollen, dann sollten Sie auf dem PrinterCnavas drucken. Hierzu müssen Sie die Pixel allerdings skalieren. Entweder Sie rechnen jeden Wert aus,(so wie hier) oder schreiben eine Funktion zum skalieren und rufen diese immer wieder auf. Oder Sie benutzen eine Windows-Funktion(SetMapMode), welches dann den Nachteil hat, dass Sie dieses Programm nicht ohne weiteres portieren können. Hier ging es ja eigentlich nur um die beiden Methoden “printer.XDPI” und “printer.YDPI”. diese sind bei den meisten Druckern gleich. Also reicht es aus einen von den beiden Werten abzurufen um die Auflösung heraus zu finden.