![]() |
Maßeinheitengenau ein Canvas ausdrucken
Seid gegrüßt, Freundinnen und Freunde,
es brennt mir mal wieder eine Frage auf dem Herzen, welche mich schon nächtelang nicht schlafen und zur Flasche greifen lässt. :) Ich möchte gerne eine mit Canvas gezeichnete Grafik mit Hilfe der TPrint-Klasse drucken. Allerdings soll der Ausdruck dann eine bestimme Größe einhalten. Beispiel: Sagen wir, ich habe eine horizontale Linie gezeichnet, welche eine spezifische Pixelanzahl lang ist, die einem centimeter entsprechend soll. Nun soll das ausgedruckte Resultat ebenfalls tatsächlich 1 cm lang sein. Beispielsweise dürften 50 Pixel auf verschiedenen Druckern unterschiedliche Längen haben, oder irre ich mich? Wie geht das? Beste Grüße und viva los tioz! PAX :nerd: |
Re: Maßeinheitengenau ein Canvas ausdrucken
Schalte den MapMode entsprechend um:
![]() |
Re: Maßeinheitengenau ein Canvas ausdrucken
Zitat:
da hast Du schon recht, aber das Problem geht noch ein kleines Stück weiter, selbst auf einem Drucker können 50 Pixel unterschiedliche Längen/Größen haben. Immerhin unterstützen die meisten Drucker unterschiedliche Auflösungen. Die Auflösung gibt nun gerade an, wieviele Pixel / Maßeinheit gesetzt werden. Je geringer also die Auflösung, desto größer jedes Pixel. Alles was Du also machen musst ist auf die Auflösung zu achten. Dazu gibt es zwei Möglichkeiten:
Das sind zwei Funktionen, die Windows zur Verfügung stellt (einfach in der API-Hilfe bzw. im PSDK nachschauen). Mit der ersten Methode setzt Du den MapMode eines Canvas. Dieser Modus passt an, in welcher Einheit Du Angaben zur Position machst. Hier kannst Du z.B. Millimeter oder zehntel millimeter wählen. Statt nun eine Linie von x-Pixeln würdest Du damit eine Linie von x-millimeter zeichnen. Mit der Methode GetDeviceCaps (ebenfalls API-Hilfe bzw. PSDK) kannst Du Eigenschaften eines Canvas abfragen. Die für Dich interessanten Eigenschaften dürften dann natürlich in der Auflösung liegen. Kennst Du die Auflösung, musst Du dich um das Umrechnen von Deinen Pixelangaben kümmern. Gruß Der Unwissende |
Re: Maßeinheitengenau ein Canvas ausdrucken
PHYSICALHEIGHT scheint mir bei der GetDeviceCaps-Funktion am zutreffendsten zu sein. Allerdings liefert die Funktion bei mir immer 0 zurück. Auch frag ich mich schon seit längerem, was der Typ "Handle" eigentlich genau ist. Ein Zeiger?
Ich kann diese ganze Druckergeschichte nicht testen, da ich keinen Drucker zur Verfügung habe, aber ich kann jeden Druck als PDF-Datei erzeugen lassen. Ist PHYSICALHEIGHT richtig? Das war das einzige, welches sich auf einen Druck mit "Geräteeinheiten" bezog. :|
Delphi-Quellcode:
if(!PrintDialog1->Execute()) return;
//Form1->Caption=SetMapMode(GetDC(Form1->Handle),MM_HIMETRIC); int i=GetDeviceCaps(GetDC(Handle),PHYSICALHEIGHT); Form1->Caption =i; |
Re: Maßeinheitengenau ein Canvas ausdrucken
Zitat:
Zitat:
Zitat:
Ansonsten bliebe der nur der Weg über die Methode EnumPrinters (Win-API), über die Du dann das Handle des Druckers ermitteln müsstest. Gruß Der Unwissende |
Re: Maßeinheitengenau ein Canvas ausdrucken
meinst du soetwas wie:
Code:
Ich habe allerdings für die Klasse TPrintDialog keine Attribute gefunden, wo ich den ausgewählten Drucker abfangen und dem Objekt der TPrinter-Klasse zuweisen kann.
TPrinter* druck = new TPrinter();
int i=GetDeviceCaps(GetDC(druck->Handle),PHYSICALHEIGHT); Form1->Caption =i; Irgendwie funktioniert es nicht so, wie ich es mir dachte. :| |
Re: Maßeinheitengenau ein Canvas ausdrucken
Nimm zum Drucken eines Bildes am besten folgenden Code
Delphi-Quellcode:
hab hier mal vor einiger Zeit Getmem durch getdibsizes ersetzt, da ich bei getmem zum teil falsche Wérte bekommen habe. Sollte so funktionieren. Den Grundcode hab ich irgendwo gegoogelt.
PROCEDURE PrintBitmap(Canvas: TCanvas; DestRect: TRect; Bitmap: TBitmap);
// PROC eingeführt am 10.1.07 da bessere ausgabeergebnisse VAR BitmapHeader: pBitmapInfo; BitmapImage,header,bits : POINTER; HeaderSize, BitsSize: Cardinal; //HeaderSize : DWORD; // Use DWORD for D3-D5 compatibility ImageSize : DWORD; nographics:boolean; BEGIN // TEST //if GetDeviceCaps(Printer.Handle, RASTERCAPS) then NoGraphics := True; GetDIBSizes(Bitmap.Handle, HeaderSize, ImageSize); //GetMem(BitmapHeader, HeaderSize); //GetMem(BitmapImage, ImageSize); Bitmapheader := VirtualAlloc(nil, HeaderSize, MEM_COMMIT, PAGE_READWRITE); BitmapImage := VirtualAlloc(nil, ImageSize, MEM_COMMIT, PAGE_READWRITE); TRY GetDIB(Bitmap.Handle, Bitmap.Palette, BitmapHeader^, BitmapImage^); StretchDIBits(Canvas.Handle, DestRect.Left, DestRect.Top, // Destination Origin DestRect.Right - DestRect.Left, // Destination Width DestRect.Bottom - DestRect.Top, // Destination Height 0, 0, // Source Origin Bitmap.Width, Bitmap.Height, // Source Width & Height BitmapImage, TBitmapInfo(BitmapHeader^), DIB_RGB_COLORS, SRCCOPY) FINALLY //FreeMem(BitmapHeader); //FreeMem(BitmapImage) VirtualFree(Bitmapheader, 0, MEM_FREE); VirtualFree(bitmapimage, 0, MEM_FREE); END END {PrintBitmap}; um dann das ganze auf eine bestimmte Größe anpassen zu können nutzt du das:
Delphi-Quellcode:
printer.title:=Dein Programmname '+filetext;
if printer.printing then printer.abort; printer.begindoc; //Drucker-Daten ermitteln: (Hoehe und Breite in cm und Pixeln) //durch 10, da mm in cm umrechnen BreiteCm :=GetDeviceCaps(Printer.Handle,HORZSIZE) div 10; BreitePixel :=GetDeviceCaps(Printer.Handle,HORZRES); HoeheCm :=GetDeviceCaps(Printer.Handle,VERTSIZE) div 10; HoehePixel :=GetDeviceCaps(Printer.Handle,VERTRES); //wieviel Pixel auf 1 cm kommen: HorizPixelProCm :=BreitePixel div BreiteCm; VertPixelProCm :=HoehePixel div HoeheCm; breitereal:=BreitePixel/BreiteCm; hoehereal:=(HoehePixel/HoeheCm); horp:= HorizPixelProCm; verp:= VertPixelProCm; faktor:=10; LRand := HorizPixelProCm; ORand :=VertPixelProCm; ... ... Printbitmap(...) printer.enddoc; gruß Matthias |
Re: Maßeinheitengenau ein Canvas ausdrucken
Zitat:
Code:
Die gibt Dir eben den aktuellen Drucker zurück, anders gesagt der TPrintDialog setzt die Variable, die hier zurückgeliefert wird für Dich. Danach sollte diese Methode eben den ausgewählten Drucker (mit eingestellten Eigenschaften) liefern. Die angesprochene Funktion sollte (bei Borland) in einer Datei wie Printers.h deklariert sein (hier kann natürlich der Name abweichen, aber denke müsste hinkommen).
TPrinter* printer(void) {...}
Zudem kannst Du das GetDC weglassen. Das ist nur nötig, wenn Du ein Fensterhandle übergeben würdest. Der Code hätte eher die Form:
Code:
Gruß
TPrinter* druck = printer();
int height = GetDeviceCaps(druck->Handle, PHYSICALHEIGHT); ... |
Re: Maßeinheitengenau ein Canvas ausdrucken
@matashen
Ich danke dir für den Code - nun kann ich gucken, wie das nachher ungefähr aussehen sollte. @soEinigesWissender :wink: Jetzt kennt der Compiler die Methode printer(), nachdem ich die Unit printers.h eingebunden habe - ich dachte zuerst noch, dass ich die nicht brauche, weil alles andere ja auch so klappte. :lol: Jetzt werden auch zu den verschiedenen dpi-Einstellungen des PDF-Writers unterschiedliche "physikalische Geräteeinheiten" zurückgegeben. Ich musste allerdings das Objekt, "druck", als global instanziieren, sonst kamen immer nach wiederholtem Abfragen des Wertes Speicherzugriffsverletzungen. @Luckie, soEinigesWissender, matashen Ich danke euch, dass ihr bereit wart, so viel Zeit in meine Fragen zu investieren! Ihr glaubt garnicht, wie viel mir immer soetwas wert ist. Ich werde mich nun mal mit dieser Sache weiter befassen, da ich denke, dass ich erstmal alles weiß, was ich dafür wissen muss. Es kann aber sein, dass sich im Laufe dessen, weitere Fragen auftun. Diesen Thread also bitte noch nicht schließen. Danke, Freunde! :) Mit besten Grüßen PAX |
Re: Maßeinheitengenau ein Canvas ausdrucken
gern geschehen :love:
:cheers: :dp: :hello: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:32 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz