Canvas auf ein anders Canvas kopieren und in eine Datei Schr

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
Antworten
pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Canvas auf ein anders Canvas kopieren und in eine Datei Schr

Beitrag von pluto »

Hallo,
ich möchte gerne in meiner "Text Engine" eine Möglichkeit haben den Canvas abzuspeichern. Jedoch sind alle meine versuche Fehl geschlagen.
Weil das Handle vom TBitmap ungültig ist.
hier meine bisherigen Versuche:

Code: Alles auswählen

plBmp:=TBitmap.Create;
      plBmp.PixelFormat:=pf32bit;
      plBmp.Width:=TextEngine.Width;
      plBmp.Height:=TextEngine.Height;
{      plBmp.Canvas.Brush.Style:=bsSolid;
      plBmp.Canvas.Brush.Color:=clBlack;
      plBmp.Canvas.Rectangle(0,0,TextEngine.Width,TextEngine.Height);
      plBmp.Canvas.Brush.Color:=clRed;
      c1:=TextEngine.Canvas;
      c2:=plBmp.Canvas;
      CopyCanvasAll(c1, c2);}
 
//      plBmp.Canvas.Ellipse(30,30,60,60);
//      r:=Rect(0,0,TextEngine.Width, TextEngine.Height);
 
      //writeln(TextEngine.Canvas.Handle);
  //    BitBlt(plBmp.Canvas.Handle,
    //         0,0,plBmp.Width, plBmp.Height,
      //       TextEngine.Canvas.Handle,0,0,SRCCOPY
//            );
  //    plBmp.Canvas.CopyRect(r,TextEngine.Canvas,r);
      SaveBMPToFile('/home/pluto/Desktop/TextEngine/B.bmp',plBmp);
//      plBmp.SaveToFile();
  //    plBmp.Free;
die Procedure SaveBmpToFile sieht so aus:

Code: Alles auswählen

procedure SaveBMPToFile(const aFileName: String; aBuffer: TBitMap);
var
  op:TOPPicture;
begin
  op:=TOpPicture.Create;
  AssignBitmapToOpBitmap(aBuffer,op.Bitmap);
  op.SaveToFile(aFilename);
  op.free;
end;
und CopyCanvasAll so

Code: Alles auswählen

procedure CopyCanvasAll(var aSrcCanvas, aDesCanvas:TCanvas);
var
  x,y:Integer;
begin
  for y:=0 to aSrcCanvas.Height do begin
    for x:=0 to aSrcCanvas.Width do begin
      aDesCanvas.Pixels[x,y]:=aSrcCanvas.Pixels[x,y];
    end; // for x
  end; // for y
end;
Frage 1) Könnt ihr bei euch ein Cavnas auf ein anders kopieren und abspeichern ?
Frage 2) Was für Möglichkeiten gibt es noch um ein Canvas in eine Date abzuspeichern.
Ich dachte ich kopiere es einfach in eine TBitmap Variable, aber leider habe ich das bis jetzt noch nicht hinbekommen. Ist das nein neuer BUG in Lazarus ?
Oder mache ich was Falsch, wenn ich was Falsch mache: Was ?
Das Bild jedenfalls bleibt immer leer.

Meine "Text Engine" zeichnet alles auf einen Canvas, selbst hier ist das handle ungültig. Und genau dieses Canvas möchte ich gerne abspeichern.
Bisher habe ich immer ein externes Programm aufgerufen, aber ich dachte eine selbst eingebaute Funktion ist besser.

Lazarus 0.9.27 Linux, Debian, Lenny KDE 3.5
MFG
Michael Springwald

bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

Re: Canvas auf ein anders Canvas kopieren und in eine Datei Schr

Beitrag von bembulak »

http://tinyurl.com/dl5hpk" onclick="window.open(this.href);return false;

Erster Eintrag - hilft das ein wenig weiter?
Sieht ja immerhin schon gut aus. Vielleicht hast du nur wo einen kleinen Denkfehler,
oder deine Komponente tut nicht so, wie du möchtest...

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Canvas auf ein anders Canvas kopieren und in eine Datei Schr

Beitrag von pluto »

Leider ! Nein. Die Handles sind einfach ungültig. Sie sind im negativen Bereich und das ist einfach Falsch. Ich habe das schon X mal gemacht auf diese art und weise.
Trotzdem Danke für deine Antwort.
MFG
Michael Springwald

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Canvas auf ein anders Canvas kopieren und in eine Datei Schr

Beitrag von pluto »

Kann das Problem jemand bestätigen ? Weil wenn ja, währe es schön wenn dieses Problem in der BUGList eingetragen werden könnte.

EDIT01: Bei dem Ersten Link kommt die gleiche Meldung, die auch bei bitblt kommt:
SrcDevBitmapToDrawable NOTE: SrcDevContext.CurrentBitmap=nil
Wie gesagt die Handles sind ungültig...
MFG
Michael Springwald

bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

Re: Canvas auf ein anders Canvas kopieren und in eine Datei Schr

Beitrag von bembulak »

Also, lass mich nochmal schauen, ob ich dich auch verstanden habe:
pluto hat geschrieben:Canvas auf ein anders Canvas kopieren und in eine Datei schreiben
Du willst vorher das bestehende Canvas auf ein Neues kopieren: Wozu? Das habe ich noch nicht kapiert, denn das Canvas als Bild zu speichern geht auch anders. Erläuter' das bitte nochmal wozu es dienen soll.
pluto hat geschrieben:ich möchte gerne in meiner "Text Engine" eine Möglichkeit haben den Canvas abzuspeichern.
Du erklärst nicht genau, WIE du das machen möchtest, aber deinem Quellcode ist zu entnehmen, dass du den Canvas als Bild speichern möchtest.
Problematisch finde ich auch, dass ich diese "TextEngine" ja gar nicht habe. Deshalb hat es relativ wenig Sinn da jetzt herum zu raten, weil:
pluto hat geschrieben:Frage 2) Was für Möglichkeiten gibt es noch um ein Canvas in eine Date abzuspeichern.
Und geanu darauf habe ich dir eine Antwort gegeben.
Folgendes funktioniert bei mir mit Lazarus 0.9.26 SVN 16885 FPC 2.2.2 Windows XP SP3 auf X86 CPU.

Code: Alles auswählen

unit Unit1; 
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ExtCtrls, Buttons, StdCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end; 
 
var
  Form1: TForm1; 
 
implementation
 
{ TForm1 }
 
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;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  Canvas.Brush.Color:= clRed;
  Canvas.Ellipse(0, 0, 20, 150);
  Canvas.Line(100, 100, 40, 30);
  Canvas.Brush.Color:= clBlue;
  Canvas.Rectangle(200, 200, 240, 270);
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
    SaveCanvas(Form1.Canvas, 'D:\Canvas01.bmp');
end;
 
 
 
initialization
  {$I unit1.lrs}
 
end.
Also wäre es um deiner Selbst Willen hilfreich, wenn du das erst mal versuchst, finde ich.
pluto hat geschrieben:Oder mache ich was Falsch, wenn ich was Falsch mache: Was ?
Wie ich schon sagte, ich vermute einen Fehler in deiner TextEngine.

_X_
Beiträge: 250
Registriert: Di 16. Dez 2008, 20:13
OS, Lazarus, FPC: aptosid (aptosid.com); Lazarus SVN gtk2+qt4; FPC 2.4.0
CPU-Target: 32/64Bit

Re: Canvas auf ein anders Canvas kopieren und in eine Datei Schr

Beitrag von _X_ »

Wenn ich deinen Code (Lazarus 0.9.27 Revision 19423) teste, dann sieht das so aus(Bild im Anhang).
Auch bei mir sind die Handles von den Canvas ungültig (Lazarus 0.9.27 Revision 19423 und Lazarus 0.9.26-4).

mfg _X_
Dateianhänge
test.bmp.zip
Bild, gepackt
(33.69 KiB) 77-mal heruntergeladen

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Canvas auf ein anders Canvas kopieren und in eine Datei Schr

Beitrag von pluto »

Du willst vorher das bestehende Canvas auf ein Neues kopieren: Wozu? Das habe ich noch nicht kapiert, denn das Canvas als Bild zu speichern geht auch anders.
Du kannst ein Canvas nun mal nicht anders speichern, als es auf ein anders zu kopieren. Es sei denn als Stream. Aber ob und wie das geht weiß ich leider nicht.
Du erklärst nicht genau, WIE du das machen möchtest, aber deinem Quellcode ist zu entnehmen
In meiner Text Engine wird alles auf ein Canvas gespeichert der wird von einer Klasse bereit gestellt die von TCustomControl abgeleitet ist. Und DIESEN Canvasn möchte ich egal wie in eine Grafik Datei bekommen. Bin für jeden Vorschlag offen. Der geht.
Also wäre es um deiner Selbst Willen hilfreich, wenn du das erst mal versuchst, finde ich.
Genau den habe ich ausprobiert und wie erwatet: Die gleiche Fehler Meldung wie bei bitblt weil CopyRect intern auf Bitblt basiert.

bembulak Trotzdem danke für deine Bemühungen. Aber das Problem sind meiner Meinung nach die ungültigen Handles. warum sie ungültig sind weiß ich nicht. Evlt. würde es ausreichen selbst passende Grafik Handles zu erzeugen. Geht das ? Wenn ja wie ? Im Übrigen macht dein Code in etwa das gleiche wie meiner. Ich habe es mit bitbtl versucht mit CopyRect, ich habe sogar versucht die Grafik per OpBitmap zu speichern nichts. Ich habe auch versucht direkt per Pixels die Pixel auf das neue Canvas zu kopieren was in einer TBitMap drin ist, was ich wiederum abspeichern kann. Egal was ich auch versuche es geht nicht.

Mein Ziel ist es einfach nur das Canvas was ich in meiner "Text Engine" habe in eine Grafik Datei abzuspeichern. Damit ich kein Externes Programm aufrufen muss dafür. Wie das geht es mir Egal. Hauptsache es geht. Meine Ideen sind mir jetzt hier ausgegangen. Das komische ist ja: Ich kann Problemlos auf das Canvas zeichnen. Alles was ich möchte. Ich kann es nur nicht abspeichern. Ich habe in Etwa die gleiche Lazarus Version wie X
Auch bei mir sind die Handles von den Canvas ungültig
Danke X. Also bin ich nicht alleine mit dem Problem und es kann auch nicht an meiner "Text Engine" liegen. Weil ein Canvas in einer Datei zu bekommen ist eigentlich keine großes Problem. Es muss sich also um ein BUG handeln.
Könntest du mal im Bugtracker nach schauen ob es da so ein Eintrag schon gibt ? ich werde auch mal schauen, wenn ich den Link gefunden habe. Kann ja sein das genau dieses Problem schon längst eingetragen wurde.
MFG
Michael Springwald

bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

Re: Canvas auf ein anders Canvas kopieren und in eine Datei Schr

Beitrag von bembulak »

Wow.
Das heißt, etwas, das hier mit 0.9.26 funktioniert, funktioniert mit 0.9.27 nicht mehr?
Schön.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Canvas auf ein anders Canvas kopieren und in eine Datei Schr

Beitrag von pluto »

Sieht so aus....
MFG
Michael Springwald

shokwave
Beiträge: 475
Registriert: Do 15. Nov 2007, 16:58
OS, Lazarus, FPC: Win11/Ubuntu Budgie (L 3.0 FPC 3.2.2)
CPU-Target: i386, x64
Wohnort: Gera

Re: Canvas auf ein anders Canvas kopieren und in eine Datei Schr

Beitrag von shokwave »

Kann ich so nicht bestätigen. Bembulaks Code läuft bei mir unter Vista und Laz0.9.27(SVN 19069) mit FPC 2.2.5.
Villeicht ein linuxspezifisches Problem.
mfg Ingo

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Canvas auf ein anders Canvas kopieren und in eine Datei Schr

Beitrag von pluto »

zwei gegen zwei *G*
Das tolle ist vorher ging es ja. Ich weiß das es bei der ich glaube 0.9.26 Problemlos geht. Oder übersehe ich was ?
MFG
Michael Springwald

Antworten