![]() |
Bitmap aus RTF erzeugen
Hi,
ich möchte aus einem RTF-Text eine Bitmap mit vorgegebenen Maßen erzeugen. Der RTF-Text liegt als MemoryStream in einem Object. Mein erster Gedanke war, mir in einer Procedure im Object temporär ein TRichEdit zu erzeugen und dann (wie ![]()
Delphi-Quellcode:
Allerdings kann ich mir den Stream nicht in das RichEdit laden, weil es kein Parent hat. Parent hab ich auch nicht, weil es ja nur ein Object ist. Jetzt dachte ich mir, ich könnte ja mittels CreateWnd sowas wie ein unsichtbares Fenster erzeugen, und das Richedit damit zufrieden stellen.
var
MyRTF: TRichEdit; begin self.FArbeitenBitmap.Height:=Height; self.FArbeitenBitmap.Width:=Width; MyRTF:=TRichEdit.Create(nil); MyRTF.Width:=Width; MyRTF.Height:=Height; Self.FArbeiten.Position:=0; MyRTF.Lines.LoadFromStream(self.FArbeiten); // <---Hier knallt's dann mal with Self.FArbeitenBitmap.Canvas do begin Lock; try myRTF.Perform(WM_PRINT, Handle, PRF_CLIENT); //you can trying to change PRF_CLIENT with //PRF_CHILDREN or PRF_CLIENT or PRF_NONCLIENT or PRF_ERASEBKGND //or combine them. See what happen... finally Unlock end; end; Wäre das so denkbar? Wenn ja, wie macht das das? Wenn nein, wie könnte man das besser machen? |
AW: Bitmap aus RTF erzeugen
Delphi-Quellcode:
sollte eigentlich funktionieren.
MyRTF := TRichEdit.CreateParented(HWND_MESSAGE);
|
AW: Bitmap aus RTF erzeugen
Danke, das löst schon mal der erste Problem.
Leider bekomme ich so
Delphi-Quellcode:
nur eine weiße Bitmap zurück.
var
MyRTF: TRichEdit; img: HDC; begin self.FArbeitenBitmap.Height:=Height; self.FArbeitenBitmap.Width:=Width; MyRTF:=TRichEdit.CreateParented(HWND_MESSAGE); MyRTF.Width:=Width; MyRTF.Height:=Height; Self.FArbeiten.Position:=0; MyRTF.Lines.LoadFromStream(self.FArbeiten); Self.FArbeitenBitmap.Canvas.Lock; try myRTF.Perform(WM_PRINT, Self.FArbeitenBitmap.Canvas.Handle, PRF_CLIENT); //you can trying to change PRF_CLIENT with //PRF_CHILDREN or PRF_CLIENT or PRF_NONCLIENT or PRF_ERASEBKGND //or combine them. See what happen... finally Self.FArbeitenBitmap.Canvas.Unlock end; Dann habe ich es noch mal so
Delphi-Quellcode:
versucht, bekomme aber eine schwarze Bitmap.
var
MyRTF: TRichEdit; img: HDC; begin self.FArbeitenBitmap.Height:=Height; self.FArbeitenBitmap.Width:=Width; MyRTF:=TRichEdit.CreateParented(HWND_MESSAGE); MyRTF.Width:=Width; MyRTF.Height:=Height; Self.FArbeiten.Position:=0; MyRTF.Lines.LoadFromStream(self.FArbeiten); img := GetDC(MyRTF.Handle); BitBlt(Self.FArbeitenBitmap.Canvas.Handle, 0, 0, MyRTF.Width, MyRTF.Height, img, 0, 0, SRCCOPY ); Im Stream ist aber definitiv das richtige drin, den wenn ich mir das in ein Richedit lade, dass auf der Form liegt, wird es korrekt angezeigt. Hast du da auch noch einen Tipp? Geht das so, außerhalb einer Form, überhaupt? |
AW: Bitmap aus RTF erzeugen
Mein Vorgehen wäre hier eher von der faulen und uneleganten Sorte:
Wenn zur Laufzeit ein TRichEdit erstellt wird und das braucht ein Formular, auf dem es liegt, dann wird das eben auch erzeugt, Visible := False, damit der Anwender da nicht genervt wird. Musste mal was ähnliches mit 'nem TChart in 'ner ISAPI.DLL machen, hat problemlos funktioniert. Vom TChart wurde auch nur das damit erstellte Bitmap benötigt. Und 'ne ISAPI.DLL mit 'nem Formular ist eher äußerst ungewöhnlich bzw. eigentlich vollkommen unsinnig. |
AW: Bitmap aus RTF erzeugen
Liste der Anhänge anzeigen (Anzahl: 3)
Habe ich grad mal versucht...keine Änderung.
Folgende Code funktioniert auf dem Formular und liefert mir eine Bitmap siehe Anhang 1:
Delphi-Quellcode:
Und folgender Code im Object funktioniert nicht und liefert mir eine Bitmap siehe Anhang 2:
var
img: HDC; begin richedit1.Lines.LoadFromStream(t.Arbeiten); t.ArbeitenBitmap.Height:=richedit1.Height; t.ArbeitenBitmap.Width:=richedit1.Width; img := GetDC(richedit1.Handle); BitBlt(t.ArbeitenBitmap.Canvas.Handle, 0, 0, richedit1.Width, richedit1.Height, img, 0, 0, SRCCOPY ); t.ArbeitenBitmap.SaveToFile(ExtractFilePath(Application.ExeName)+'arbeiten.bmp');
Delphi-Quellcode:
Sollte doch eigentlich gehen. Woran kann das liegen?
var
MyRTF: TRichEdit; frm: TForm; img: HDC; begin self.FArbeitenBitmap.Height:=Height; self.FArbeitenBitmap.Width:=Width; frm:=TForm.Create(Application); try //MyRTF:=TRichEdit.CreateParented(HWND_MESSAGE); MyRTF:=TRichEdit.Create(frm); Try MyRTF.Parent:=frm; MyRTF.Width:=Height; MyRTF.Height:=Width; Self.FArbeiten.Position:=0; MyRTF.Lines.LoadFromStream(self.FArbeiten); img := GetDC(MyRTF.Handle); BitBlt(Self.FArbeitenBitmap.Canvas.Handle, 0, 0, MyRTF.Width, MyRTF.Height, img, 0, 0, SRCCOPY ); finally MyRTF.free; End; finally frm.free; end; Man kann das zweite Bild unten leder nicht so richtig sehen, ist aber da. Ist halt komplett weiß ;-) Das linke Bild ist Anhang 1 und das rechte ist Anhang 2. |
AW: Bitmap aus RTF erzeugen
Kann gerade nicht testen, kein Delphi in der Nähe :-(
Gibt dem Formular bitte mal 'ne Höhe und Breite, die der des gewünschten Bitmaps plus Höhe von Caption, Border ... des Forms entspricht und mach' das Formular erstmal sichtbar, um so eine "quasioptische" Kontrolle zu haben, ob überhaupt was zu sehen ist. |
AW: Bitmap aus RTF erzeugen
Hab ich gemacht:
Delphi-Quellcode:
Formular erscheint. RichEdit ist drauf und Text im Richedit ist korrekt.
var
MyRTF: TRichEdit; frm: TForm; img: HDC; begin self.FArbeitenBitmap.Height:=Height; self.FArbeitenBitmap.Width:=Width; frm:=TForm.Create(Application); try frm.Width:=Width+50; frm.Height:=Height+80; //MyRTF:=TRichEdit.CreateParented(HWND_MESSAGE); MyRTF:=TRichEdit.Create(frm); Try MyRTF.Left:=10; MyRTF.Top:=20; MyRTF.Parent:=frm; MyRTF.Width:=Width; MyRTF.Height:=Height; frm.Visible:=True; Self.FArbeiten.Position:=0; MyRTF.Lines.LoadFromStream(self.FArbeiten); img := GetDC(MyRTF.Handle); BitBlt(Self.FArbeitenBitmap.Canvas.Handle, 0, 0, MyRTF.Width, MyRTF.Height, img, 0, 0, SRCCOPY ); finally //MyRTF.free; End; finally //frm.free; end; Bitmap ist aber trotzdem nur weiß. Erklären kann ich mir das nicht. |
AW: Bitmap aus RTF erzeugen
Hab aber grad heraus gefunden, dass, wenn ich nach dem LoadFromStream ein Applicaiton.processMessages mache, dann wird die Bitmap korrekt erstellt ;-)
Nur ein Application.ProcessMessages in einem Object......ist nicht wirklich eine gute Idee. Wie kann ich dem RichEdit sage, dass es seinen geladenen Stream aufbereiten soll, damit ich danach das Bitmap erstellen kann? [Edit] und wenn ich das Visible für die frm wieder rausnehme, ist meine Bitmap wieder schwarz :-( [/Edit] |
AW: Bitmap aus RTF erzeugen
Blöd das Ganze:
Left des Formulars auf -1000 oder sowas setzen, dann kann es sichtbar bleiben, ist aber außerhalb des sichtbaren Bereiches. Kann RichEdit Repaint, Update oder sowas? Weiß, meine Vorschläge sind irgendwie wieder grenzwertig, zumindest mir gefallen sie nicht :-( |
AW: Bitmap aus RTF erzeugen
Hmm..
Hab mal nen bischen gegooglet und zusmmengeschripselt: (Vergessen die Quellen zu notieren.. )
Delphi-Quellcode:
uses
Windows, Classes, Graphics, ComCtrls, RichEdit; procedure DrawRTF(DestDCHandle: HDC; const R: TRect; RichEdit: TRichEdit; PixelsPerInch: Integer); var TwipsPerPixel: Integer; Range: TFormatRange; begin TwipsPerPixel := 1440 div PixelsPerInch; Range.hDC := DestDCHandle; {DC handle} Range.hdcTarget := DestDCHandle; {ditto} {Convert the coordinates to twips (1/1440")} Range.rc.Left := R.Left * TwipsPerPixel; Range.rc.Top := R.Top * TwipsPerPixel; Range.rc.Right := R.Right * TwipsPerPixel; Range.rc.Bottom := R.Bottom * TwipsPerPixel; Range.rcPage := Range.rc; {Start at character zero} Range.chrg.cpMin := 0; {Display all Characters} Range.chrg.cpMax := -1; {RichEdit.GetTextLen;} {Free cached information} RichEdit.Perform(EM_FORMATRANGE, 0, 0); {First measure the text, to find out how high the format rectangle will be. The call sets fmtrange.rc.bottom to the actual height required, if all characters in the selected range will fit into a smaller rectangle} RichEdit.Perform(EM_FORMATRANGE, 0, DWord(@Range)); {Now render the text} RichEdit.Perform(EM_FORMATRANGE, 1, DWord(@Range)); {Free cached information} RichEdit.Perform(EM_FORMATRANGE, 0, 0); end; procedure RTFToBmp(MainWND : HWND;AFileName : string;var ABitMap : TBitmap); var RichEdit: TRichEdit; DestDCHandle: HDC; begin RichEdit :=TRichEdit.CreateParented(MainWND); try RichEdit.Width := GetDeviceCaps(GetDC(RichEdit.Handle),VERTRES); RichEdit.Height := GetDeviceCaps(GetDC(RichEdit.Handle),HORZRES); RichEdit.Visible := False; RichEdit.Lines.LoadFromFile(AFileName); ABitMap.width := RichEdit.Width; ABitMap.height := RichEdit.Height; DestDCHandle := ABitMap.Canvas.Handle; DrawRTF(DestDCHandle, Rect(0, 0, ABitMap.Width, ABitMap.Height), RichEdit, 96); finally RichEdit.Free; end; end; Aufruf:
Delphi-Quellcode:
Damit erhalte ich ein Bitmap der ersten Seite des RTF Dokumentes...
procedure TForm1.Button1Click(Sender: TObject);
var tmpBMP : TBitMap; begin if OpenDialog1.Execute then begin tmpBMP := TBitMap.Create; try RTFToBmp(self.Handle,OpenDialog1.FileName,tmpBMP); Image1.Picture.Assign(tmpBMP); finally tmpBMP.Free; end; end; end; (Getestet mit D6...) |
AW: Bitmap aus RTF erzeugen
Ich hab das mal so ziemlich unverändert übernommen. Ich erhalte leider nur eine leere, weiße Bitmap in (ca. A4-Größe)
Der einzige Unterschied ist, dass ich die Bitmap bereit in meinem Objekt habe, und demnach nicht übergeben muss, und dass ich das Richedit aus einem MemoryStream lade. |
AW: Bitmap aus RTF erzeugen
Hmm..
Mach mal ein neues Project, pappe da nen Button, OpenDialog und ein TImage drauf und verwende mal meinen Src. (Nur um zu prüfen) Wenn dann das bmp nicht mehr weiß ist und das PDF enthält, gehst Du hin und testest, mit deinem Stream. Somit kannst Du schonmal ausschließen, ob es die Routine mit dem RichEdit ist. Oder dass der Stream leer ist.. Schritt für Schritt.. ;) |
AW: Bitmap aus RTF erzeugen
mach ich gleich mal. Aber dass der Stream nicht leer ist, habe ich schon geprüft, und sichergesellt (s. einem der oberen Posts).
Aber ich probier das jetzt mit einem neuen Projekt mal aus. |
AW: Bitmap aus RTF erzeugen
Danke Holger,
ich habe das jetzt noch mal in einem neuen Projekt gemacht. Und natürlich funktioniert's ;-) Warum es vorher in meine Zielprojekt nicht funktioniert hat ich auch herausgefunden. Jetzt muss ich das nur noch so abändern, dass ich die Bitmap.Height und .Width übergeben kann. :-) |
AW: Bitmap aus RTF erzeugen
Gut.. :thumb:
Ich mache mir bei so Problemen immer ein kleines Testprogramm, indem ich die Funktionen oder auch Klassen in einer minimalen Umgebung teste, somit kann ich sicherstellen, dass diese Funktionieren und kann meine Suche dann in eine Andere Richtung bewegen.. ;) Apropo, woran hat es denn nun gelegen? |
AW: Bitmap aus RTF erzeugen
Mach ich des Öfteren auch. Allerdings war der Code sehr überschaubar, dass ich annahm, einen Testprojekt sei nicht notwendig.
Tja...ich hatte nur ein Assign vergessen ;-) |
AW: Bitmap aus RTF erzeugen
Zitat:
vielen Dank für Deinen Beitrag, der mir schon sehr weiter geholfen hat. Das einzige Problem, dass ich noch habe, ist, dass ich das Bitmap mit einer höheren Auflösung erstellen möchte. Das gelingt mir insofern nicht, dass sich die Pixelauflösung des RtfTextes in der Bitmap nicht erhöht. Ich habe heute viele Stunden dran gesessen, finde aber nicht die Lösung :( . Hast Du oder jemand anders eine Idee, wie man Dein Beispiel korrekt anpasst? Uli |
AW: Bitmap aus RTF erzeugen
Ich meine, es geht mit ViewPort. Nur wie?
Edit: nach einem kompletten Wochenende der Rumsucherei habe ich gestern Abend kurz vor dem zu Bett gehen auf dem iPhone die Lösung gefunden. Und siehe da, beim Suchen nach "Delphi" und "Viewport" fand ich einen vielversprechenden Link auf einen Faden in diesem Forum: https://www.delphipraxis.net/40461-k...as-zoomen.html Ich denke, damit werde ich schnell mein Problem lösen. - Bleibt die Frage, warum ich über das Suchfeld und sonstige Suchen den Faden nicht früher gefunden habe. Klar, das Problem sitzt vor dem Bildschirm ... Ich habe im Suchfeld nicht gemerkt, dass immer nur nach ganzen Wörtern gesucht wird und nicht nach Teilworten. Ein "*" hinter "Viewport" hinzugefügt und schon habe ich aus so die entscheidenden Fäden gefunden. |
AW: Bitmap aus RTF erzeugen
Hallo Uli,
ich stehe grad selbst vor dem gleichen Problem. Es wäre schön, wenn du deine Lösung hier allen zur Verfügung stellst um wiederholte "Rumsucherei" zu erübrigen. ;) |
AW: Bitmap aus RTF erzeugen
Sorry, die Lösung, die ich da gefunden hatte, war im Endeffekt auch nicht besonders gut. Ich habe es dann komplett selbst programmiert.
|
AW: Bitmap aus RTF erzeugen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:50 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-2025 by Thomas Breitkreuz