| Autor |
Beitrag |
Nitr0
Hält's aus hier
Beiträge: 11
|
Verfasst: So 13.04.08 15:40
Hi,
habe ein Problem.
Ich will in Delphi ein Bild, das auf eine Leinwand (Canvas), die "in" einer Paintbox steckt, gemalt wurde, per SaveImageDialog (oder SaveDialog, spielt eigentlich keine Rolle) speichern. Das Problem ist nur, sobald das Fenster fürs Speichern geöffnet wird, wird die Canvas gelöscht, also wird immer nur ein leeres Bild gespeichert.
Habe schon probiert, vor dem Speichern ein Canvas.Lock durchzuführen und bei OnClose oder OnCanClose vom SaveDialog wieder zu Unlocken, aber dabei hängt sich meistens das Programm auf.
Wer kann mir helfen?
Danke schonmal. 
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: So 13.04.08 17:17
Das Locken ist für Thread-sichere Anwendungen.
Du hättest aber unmittelbar danach eh ein Problem, da man Canvas nicht einfach so speichern kann. Lösung:
-TBitmap erzeugen
-Canvas rein kopieren
-Dialog aufrufen
-Bitmap speichern
-Freigeben nicht vergessen
Hth,
Martok
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
Nitr0 
Hält's aus hier
Beiträge: 11
|
Verfasst: So 13.04.08 21:15
Ja, diese Möglichkeit habe ich danach ausprobiert.
Dazu habe ich folgendes gecodet:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TForm1.Button5Click(Sender: TObject); var Zwischenspeicher:TCanvas; _Rect:TRect; begin _Rect := Rect(Paintbox1.Left,Paintbox1.Top,Paintbox1.Left+PaintBox1.Width,Paintbox1.Top+PaintBox1.Height); Zwischenspeicher:=Canvas.Create; Zwischenspeicher.CopyRect(_Rect,Paintbox1.Canvas,_Rect); if SavePictureDialog1.Execute then SaveCanvas(Zwischenspeicher,SavePictureDialog1.FileName); end; |
SaveCanvas ist definiert wie folgt:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure SaveCanvas(SaveCanvas: TCanvas; FileName: string); var Bmp: TBitmap; MyRect: TRect; begin Bmp := TBitmap.Create; try MyRect := SaveCanvas.ClipRect; Bmp.Width := MyRect.Right - MyRect.Left; Bmp.Height := MyRect.Bottom - MyRect.Top; Bmp.Canvas.CopyRect(MyRect, SaveCanvas, MyRect); Bmp.SaveToFile(FileName); finally FreeAndNil(Bmp); end; end; |
Doch damit klappt es auch nicht.
Wenn ich einfach nur SaveCanvas mache, klappt es. Nur, wenn der Dialog geöffnet wird geht es nicht.
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Mo 14.04.08 08:15
probiers mal so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| procedure TForm1.Button5Click(Sender: TObject); var Zwischenspeicher:TCanvas; _Rect:TRect; FName: String; begin _Rect := Rect(Paintbox1.Left,Paintbox1.Top,Paintbox1.Left+PaintBox1.Width,Paintbox1.Top+PaintBox1.Height); Zwischenspeicher:=Canvas.Create; Zwischenspeicher.CopyRect(_Rect,Paintbox1.Canvas,_Rect); if SavePictureDialog1.Execute then begin FName := SavePictureDialog1.Filename; SaveCanvas(Zwischenspeicher,FName); end; end; |
lg elundril
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
Nitr0 
Hält's aus hier
Beiträge: 11
|
Verfasst: Mo 14.04.08 20:22
Danke erstmal auch für den Post.
Macht aber leider keinen Unterschied.
Es wird jetzt immer nur ein Bild vom Programmfenster gespeichert das dort wo der SaveDialog ist eine weiße Fläche und irgendeinen Speichern Icon hat. Aber das war auch schon davor so, ohne die FName Variable.
Ich häng das erzeugte Bild mal an... 
Einloggen, um Attachments anzusehen!
|
|
Nitr0 
Hält's aus hier
Beiträge: 11
|
Verfasst: Di 15.04.08 22:46
Habe es selber gelöst, danke trotzdem.
Andere Frage: Ich will es jetzt schaffen, ein Bild per OpenPictureDialog in die Canvas reinzuladen. Habe dazu Folgendes geschrieben:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm1.Button6Click(Sender: TObject); var Bild : TBitmap; begin if OpenPictureDialog1.Execute then begin Bild.LoadFromFile(OpenPictureDialog1.FileName); Paintbox1.Canvas.Draw(0,0,Bild); end; end; |
Doch er bringt mir immer die Fehlermeldung dass die Variable Bild wahrscheinlich nicht initialisiert wurde.
Wie kann ich das beheben?
|
|
jaenicke
      
Beiträge: 19333
Erhaltene Danke: 1750
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 16.04.08 04:55
Du musst von einer Klasse zuerst eine Instanz erzeugen und diese in die Variable tun, danach kannst du damit arbeiten: Delphi-Quelltext 1:
| Bild := TBitmap.Create; | Wichtig: Du musst den Speicher dieser Instanz auch wieder freigeben! Delphi-Quelltext
Dann noch etwas anderes:
Ich würde statt einer TPaintBox ein TImage benutzen, dann hast du auch nicht das Problem, dass deine Zeichenfläche gelöscht wird, wenn ein anderes Fenster davor geschoben wird.
|
|
Nitr0 
Hält's aus hier
Beiträge: 11
|
Verfasst: Mi 16.04.08 13:16
Danke schonmal, ich probier das gleich mal aus.
Das mit dem TImage hab ich mir auch schon gedacht, im Unterricht haben wir halt mit PaintBox angefangen. 
|
|
|