Farbmixer in Lazarus

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Lapiz123
Beiträge: 9
Registriert: Do 14. Jan 2021, 20:42

Farbmixer in Lazarus

Beitrag von Lapiz123 »

k
Zuletzt geändert von Lapiz123 am Di 9. Mär 2021, 19:26, insgesamt 1-mal geändert.

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
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

Beitrag von corpsman »

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

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

Re: Farbmixer in Lazarus

Beitrag von wp_xyz »

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) 83-mal heruntergeladen

Lapiz123
Beiträge: 9
Registriert: Do 14. Jan 2021, 20:42

Re: Farbmixer in Lazarus

Beitrag von Lapiz123 »

öö
Zuletzt geändert von Lapiz123 am Di 9. Mär 2021, 19:27, insgesamt 1-mal geändert.

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

Re: Farbmixer in Lazarus

Beitrag von wp_xyz »

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.
Dateianhänge
color_mixer.png
color_mixer.png (6.48 KiB) 1448 mal betrachtet
color_mixture2.zip
(2.72 KiB) 94-mal heruntergeladen

Lapiz123
Beiträge: 9
Registriert: Do 14. Jan 2021, 20:42

Re: Farbmixer in Lazarus

Beitrag von Lapiz123 »

ok
Zuletzt geändert von Lapiz123 am Di 9. Mär 2021, 19:27, insgesamt 1-mal geändert.

Lapiz123
Beiträge: 9
Registriert: Do 14. Jan 2021, 20:42

Re: Farbmixer in Lazarus

Beitrag von Lapiz123 »

thx
Zuletzt geändert von Lapiz123 am Di 9. Mär 2021, 19:27, insgesamt 1-mal geändert.

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

Re: Farbmixer in Lazarus

Beitrag von wp_xyz »

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?
Offenbar hast du dann den Code nicht verstanden. Vielleicht wird's mit diesen Kommentaren klarer:

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;

Antworten