Problem mit canvas.pen.color

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
ErnstVolker
Beiträge: 326
Registriert: Di 17. Feb 2009, 10:44
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Problem mit canvas.pen.color

Beitrag von ErnstVolker »

Ich habe das Progrämm mal bei mir zum laufen gebracht. Bei mir werden rote Kreise mit schwarzem Punkt in das Bild gezeichnet. Allerdings bei "Bild ind Datei speichern" werden die Kreise mit Punkt nicht übernommen.
Lazarus 2.0.4, 64 bit, FPC 3.0.4, SVN-Revision 61665

In diesem Zusammenhang bin ich inzwischen bei einem ähnlichen Problem mit TImage angekommen. Ich habe ein TImage in einer Scrollbox auf einem Formular. Jetzt klicke ich auf dem in das TImgae geladenen Bild nacheinander vier Punkte an. Da werden auch schön vier Kringel genau an die Stellen gezeichnet die ich angeklickt habe. Zwischen zwei Kringeln befinden sich Linien, das geht auch.

Setze ich jedoch den ersten Punkt auf das Bild und schiebe dann an einer der Scrollbars (egal ob horizontal oder vertikal) und will danach die restlichen drei Punkte setzen, dann werden die an völlig falscher Position angezeigt. Und folglich auch die Linien dazwischen.
Auf die Berechnung, die nach dem Klicken der Punkte erfolgt und über separaten Knopf ausgelöst wird, hat es keinen negativen Einfluss. D.h. die angepickten Punkte des Bildes werden richtig erfasst, nur die zugehörigen Kreise und Linien falsch positioniert.

alpinus
Beiträge: 13
Registriert: Di 6. Jan 2009, 08:05

Re: Problem mit canvas.pen.color

Beitrag von alpinus »

Ja, das ist das seltsame - auf einem Rechner werden die roten Kreise richtig gezeichnet aber nicht gespeichert, auf einem anderen Rechner werden die Kreise weiß gezeichnet, dafür aber gespeichert...

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Problem mit canvas.pen.color

Beitrag von wp_xyz »

Ich denke, das passiert, weil du auf dem Canvas der TImage-Komponente zeichnest, das ist aber nicht der Canvas des Bitmaps, das du per Picture.Assign beim Speichern an die Datenbank übergibst.

Wenn ich nun in Image3MouseUp die Zeile "with Image3.Canvas" durch "with Image3.Picture.Bitmap.Canvas" ersetze, werden die gezeichneten Ringe tatsächlich in der DB gespeichert. Aber nun habe ich das geschilderte Problem, dass die Kreise nicht mehr rot sondern bei mir grau, bei dir weiß, also durchsichtig, sind. Interessanterweise sind die Kreise korrekt dargestellt, wenn ich ein SaveToFile ans Ende der Zeichenroutine setze und die erzeugte Datei mir extern ansehe!

Ich habe noch nie so genau verstanden, was die visuellen Komponenten alles mit der Transparenz anstellen. Abhilfe ist, den Umweg über ein LazIntfImage zu nehmen. Dazu musst du den Zeichen-Code im OnMouseUp Event des Image3 ersetzen durch:

Code: Alles auswählen

uses
  FPImage, LazCanvas, IntfGraphics;
var
  intfImg: TLazIntfImage;
  cnv := TLazCanvas;
...
  intfImg := Image3.Picture.Bitmap.CreateIntfImage;
  try
    cnv := TLazCanvas.Create(intfImg);
    try
      cnv.Pen.Width := 5;
      cnv.Pen.FPColor := colRed;
      cnv.Brush.Style := bsClear;
      cnv.Ellipse(x0-30, y0-30, x0+30, y0+30);
      cnv.Pen.FPColor := colBlack;
      cnv.Brush.Style := bsSolid;
      cnv.Brush.FPColor := colBlack;
      cnv.Ellipse(x0-1, y0-1, x0+1, y0+1);
    finally
      cnv.Free;
    end;
    Image3.Picture.Bitmap.LoadfromIntfImage(intfImg);
  finally
    intfImg.Free;
  end;

Problem an dieser Lösung: TLazCanvas unterstützt bei Kreisen offenbar den Pen.Width-Parameter nicht, d.h. die Kreise werden nur 1 Pixel dick. Na dann halt 5 Kreise mit je 1Pixel enger werdendem Radius? Nein, nun gibt es immer wieder Lücken zwischen den roten Pixeln, was unschön aussieht.

Vielleicht fällt mir noch etwas besseres ein...

alpinus
Beiträge: 13
Registriert: Di 6. Jan 2009, 08:05

Re: Problem mit canvas.pen.color

Beitrag von alpinus »

Hallo wp_xyz,

das mit der Transparenz scheint ein Problem zu sein, doch der Umweg über LazIntfImage funktioniert. Klar, bei 5 Ringen erscheinen unschönen Pixel, aber bei meiner Anwendung kommt es eher auf die Funktionalität an als auf die absolut perfekte Optik.

Also erstmal herzlichen Dank und Gruß,
Alpinus

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Problem mit canvas.pen.color

Beitrag von wp_xyz »

Ohne es jetzt explizit getestet zu haben, meine ich, dass ich schon mal mit Canvas.Line mit Pen.Width > 1 erfolgreich auf einem LazIntfImage gezeichnet habe. Daher könntest du den Kreis als Polygonzug annnähern und als PolyLine oder - falls dies auch nicht geht - als Sequenz von Canvas.Line-Anweisungen ausgeben.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Problem mit canvas.pen.color

Beitrag von Winni »

Hi!

Erspar Dir doch viel Arbeit und benutze BGRAbitmap.
Falls noch nicht installiert gibt's das beim Online-Manager.

Und dann ganz simple:

Code: Alles auswählen

 
uses .... BGRAbitmap, ,BGRAdefaultBitmap;
 
procedure TForm1.Test1Click(Sender: TObject);
var tmp :TBGRABitmap;
begin
image2.canvas.brush.color := clWhite;
image2.canvas.FillRect(0,0,image2.width,image2.height);
 
tmp := TBGRABitmap.create (Image2.Width,Image2.height);
tmp.EllipseAntialias(x0,y0,30,30,clRed,5);
tmp.EllipseAntialias(x0,y0,1,1,clBlack,5);
tmp.Draw(Image2.canvas, Rect(0,0,tmp.width,tmp.height),false);
tmp.free;
end;
 


BGRAbitmap vereinfacht die Arbeit mit Graphik wirklich erheblich.

Winni

Antworten