Farbmixer in Lazarus
Farbmixer in Lazarus
k
Zuletzt geändert von Lapiz123 am Di 9. Mär 2021, 19:26, insgesamt 1-mal geändert.
- corpsman
- Lazarusforum e. V.
- Beiträge: 1629
- Registriert: Sa 28. Feb 2009, 08:54
- OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
- CPU-Target: 64Bit
- Wohnort: Stuttgart
- Kontaktdaten:
Re: Farbmixer in Lazarus
Da empfehle ich mal direct das mit OpenGL zu machen, da kannst es einfach Blenden lassen dürfte dort nur wenige Zeilen Code sein 

--
Just try it
Just try it
Re: Farbmixer in Lazarus
Das geht auch mit LCL, allerdings nur pixelweise: Die Mittelpunkte der roten, grünen und blauen Kreise merken. Dann, wenn ein Pixel gesetzt werden soll, den Abstand vom jeweiligen Mittelpunkt berechnen (es reicht das Quadrat) und wenn dieser kleiner ist als der Kreisradius, die Farbkomponente entsprechend setzen. Statt der Pixels[]-Eigenschaft, arbeite ich mit einem LazIntfImage, damit geht's schnell genug und plattformübergreifend (wahrscheinlich geht es aber auch in Delphi-Manier mit Scanline)
- Dateianhänge
-
color_mixture.zip
- (2.49 KiB) 97-mal heruntergeladen
Re: Farbmixer in Lazarus
öö
Zuletzt geändert von Lapiz123 am Di 9. Mär 2021, 19:27, insgesamt 1-mal geändert.
Re: Farbmixer in Lazarus
Ich habe das Demoprogramm jetzt erweitert, so dass der Farbwert in der Mitte ausgelesen und nochmals separat in einem Panel angezeigt wird.
Also ich weiß nicht, ob es nur mir so geht, aber ich habe den Eindruck, dass auf dem Panel eine andere Farbe erscheint als in der Schnittfläche aller drei Kreise. Ich habe mit einem ScreenColorPicker die Farben extra manuell ausgelesen, und sie sind identisch. Wahrscheinlich wird das visuelle Farbempfinden durch die Anwesenheit der Nachbarkreise verfälscht. Daher halte ich diesen Farbmischer nicht für sehr geeignet.
Also ich weiß nicht, ob es nur mir so geht, aber ich habe den Eindruck, dass auf dem Panel eine andere Farbe erscheint als in der Schnittfläche aller drei Kreise. Ich habe mit einem ScreenColorPicker die Farben extra manuell ausgelesen, und sie sind identisch. Wahrscheinlich wird das visuelle Farbempfinden durch die Anwesenheit der Nachbarkreise verfälscht. Daher halte ich diesen Farbmischer nicht für sehr geeignet.
- Dateianhänge
-
- color_mixer.png (6.48 KiB) 1633 mal betrachtet
-
color_mixture2.zip
- (2.72 KiB) 105-mal heruntergeladen
Re: Farbmixer in Lazarus
ok
Zuletzt geändert von Lapiz123 am Di 9. Mär 2021, 19:27, insgesamt 1-mal geändert.
Re: Farbmixer in Lazarus
thx
Zuletzt geändert von Lapiz123 am Di 9. Mär 2021, 19:27, insgesamt 1-mal geändert.
Re: Farbmixer in Lazarus
Offenbar hast du dann den Code nicht verstanden. Vielleicht wird's mit diesen Kommentaren klarer:Lapiz123 hat geschrieben: Mo 8. Feb 2021, 00:56 Danke nochmal für die große Hilfe mittlerweile konnte ich mein Projekt komplett beenden. Fehlt noch nur noch die Kommentierung. Wärst du so nett und würdest diese für folgende Part hinzufügst?
Code: Alles auswählen
// Berechnet das Quadrat des Abstands des Pixels am Ort (i, j) von dem Punkt P
function Distance2(i, j: Integer; P: TPoint): Integer;
begin
Result := sqr(i-P.X) + sqr(j-P.Y);
end;
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
P1, P2, P3: TPoint;
R, Rsq: Integer;
bmp: TBitmap;
img: TLazIntfImage;
HBmp, HMask: HBitmap;
clr: TFPColor;
i, j: Integer;
begin
// Radius jedes Farbkreises
R := Paintbox1.Width div 3;
Rsq := R*R;
// Mittelpunkte der Farbkreise
P1 := Point(R, R);
P2 := Point(Paintbox1.Width - R, R);
P3 := Point(Paintbox1.Width div 2, PaintBox1.Height - R);
// Wir zeichnen zunnächst auf einem Bitmap
bmp := TBitmap.Create;
try
bmp.SetSize(Paintbox1.Width, Paintbox1.Height);
bmp.PixelFormat := pf24bit;
bmp.Canvas.Brush.Color := clBlack;
bmp.Canvas.FillRect(0, 0, bmp.Width, bmp.Height);
// Um die Farben einzeln ansprechen zu können, wird das Bitmap in ein
// LazIntfImage umgewandelt (es gäbe aber auch andere Möglichkeiten).
img := bmp.CreateIntfImage;
try
// Alle Pixel (i, j) des LazIntfImage durchlaufen
for j := 0 to img.Height-1 do
for i := 0 to img.Width - 1 do
begin
// Farb-Record des Pixels am Ort (i, j)
clr := img.Colors[i, j];
// Wenn der Abstand des aktuellen Pixels (i, j) vom Mittelpunkt des
// roten Kreises kleiner ist als der Kreisradius, wird die rote
// Farbkomponente auf dem in der roten Scrollbar vorgegebenen Wert gesetzt.
// Da sich die Beziehung a<b nicht ändert, wenn man sie quadriert, werden
// hier statt den Abständen lediglich die Quadrate der Abstände verglichen.
if Distance2(i, j, P1) <= Rsq then
clr.Red := sbRed.Position shl 8;
// Jede Farbkomponente im LazIntfImage hat 16 bit, in TColor nur 8 bit.
// Durch die "shl 8"-Operation werden die 8 Bit um 8 Positionen ins High-Byte von clr.Red verschoben.
// genauso mit grün...
if Distance2(i, j, P2) <= Rsq then
clr.Green := sbGreen.Position shl 8;
// ... und mit blau.
if Distance2(i, j, P3) <= Rsq then
clr.Blue := sbBlue.Position shl 8;
img.Colors[i, j] := clr;
end;
// Inhalt des LazIntfImage auf das Zeichenbitmap übertragen
img.CreateBitmaps(HBmp, HMask);
bmp.BitmapHandle := HBmp;
bmp.MaskHandle := HMask;
finally
img.Free;
end;
// Zeichenbitmap auf der Paintbox ausgeben.
Paintbox1.Canvas.Draw(0, 0, bmp);
finally
bmp.Free;
end;
end;