35 votes

Bitmap et couleurs de Firemonkey (FMX)

Supposons que j'ai un petit bitmap dans Firemonkey (disons 32x24 pixels). Je place donc un TImage sur un formulaire et dans le constructeur il y a ce code :

  Image1.Bitmap.Create(32, 24);
  if Image1.Bitmap.Canvas.BeginScene then
  try
    Image1.Bitmap.Canvas.Fill.Color := claBlack;
    Image1.Bitmap.Canvas.Stroke.Color := claYellow;
    Image1.Bitmap.Canvas.FillRect(RectF(0,0,32,24), 0, 0, AllCorners, $FF);
    Image1.Bitmap.Canvas.DrawLine(PointF(1,1), PointF(10,10), $FF);
  finally
    Image1.Bitmap.Canvas.EndScene;
    Image1.Bitmap.BitmapChanged;
  end;

Cela dessine une belle ligne diagonale sur le fond noir.

Ce que je veux faire maintenant, c'est analyser le bitmap pour déterminer les pixels affectés par le tracé de la ligne. Si je fais une vérification basique pixel par pixel en utilisant :

  for y := 0 to 23 do
    for x := 0 to 31 do
      if Image1.Bitmap.Pixels[x,y] <> claBlack then
        memo1.Lines.Add(Format('x=%d. y=%d. c=%x', [x,y,Image1.Bitmap.Pixels[x,y]]));

la sortie sur mon Memo est :

x=0. y=0. c=FF3C3C00
x=1. y=0. c=FF3C3C00
x=0. y=1. c=FF3C3C00
x=1. y=1. c=FFE7E700
x=2. y=1. c=FF3C3C00
x=1. y=2. c=FF3C3C00
x=2. y=2. c=FFE7E700
x=3. y=2. c=FF3C3C00
x=2. y=3. c=FF3C3C00
x=3. y=3. c=FFE7E700
x=4. y=3. c=FF3C3C00
x=3. y=4. c=FF3C3C00
x=4. y=4. c=FFE7E700
x=5. y=4. c=FF3C3C00
x=4. y=5. c=FF3C3C00
x=5. y=5. c=FFE7E700
x=6. y=5. c=FF3C3C00
x=5. y=6. c=FF3C3C00
x=6. y=6. c=FFE7E700
x=7. y=6. c=FF3C3C00
x=6. y=7. c=FF3C3C00
x=7. y=7. c=FFE7E700
x=8. y=7. c=FF3C3C00
x=7. y=8. c=FF3C3C00
x=8. y=8. c=FFE7E700
x=9. y=8. c=FF3C3C00
x=8. y=9. c=FF3C3C00
x=9. y=9. c=FFE7E700
x=10. y=9. c=FF3C3C00
x=9. y=10. c=FF3C3C00
x=10. y=10. c=FF3C3C00

donc il interprète et "brouille" ? ma ligne car les couleurs (représentées par c ci-dessus) ne sont pas égales à claYellow ($FFFF00). Si je dessine une ligne horizontale ou verticale, l'effet est le même. Si je change l'épaisseur de mon trait à 2 et que je dessine une ligne non diagonale, elle se dessine en jaune claYellow mais elle couvre 2 pixels.

Alors comment puis-je déterminer les "vrais" pixels sur lesquels j'ai dessiné. Dans l'exemple ci-dessus, je chercherais (pourrais) $FFE7E700 mais comment savoir si je dois chercher cette valeur (étant donné que si j'avais dessiné la ligne dans une autre couleur, cette valeur serait différente). J'ai essayé de voir s'il y avait une "différence" cohérente entre la couleur avec laquelle j'ai dessiné et la couleur réelle rendue, mais je n'ai pas réussi à en trouver une.

Merci

5voto

Yaroslav Brovin Points 202

FMX utilise un antigel pour le dessin. Si vous souhaitez dessiner une ligne sans effet de flou, vous devez utiliser une fonction spéciale pour l'alignement des pixels :

  • TCanvas.AlignToPixel
  • TCanvas.AlignToPixelVertically (alignement vertical des pixels)
  • TCanvas.AlignToPixelHorizontally (alignement horizontal)

Cette fonction calcule automatiquement la position des pixels pour un dessin sans flou.

Merci.

1voto

biaxynte Points 11

Les couleurs dans l'exemple sont anticrénelées, ce qui signifie qu'elles sont en partie la couleur que vous avez définie et en partie la couleur de fond. Le rapport précis est basé sur de nombreuses considérations faites en coulisses.

Je ne connais pas bien FireMonkey (ou Delphi), donc je ne peux pas vous dire s'il y a un moyen de contourner ce problème, mais si vous voulez savoir où se trouve une certaine couleur, vous pouvez tester les rapports entre les valeurs RVB, en supposant que vous ne traciez qu'une seule ligne sur un fond noir (sinon, les rapports doivent être une gamme pour attraper les pixels avec de grandes quantités de bruit).

exemple : jaune(#ffff00)

rouge/vert=1

rouge/bleu=vert/bleu=#inf(ou si vous voulez, 255/1=255)

un pixel échantillonné pourrait être #fcfc00 en conservant les ratios

un pixel échantillonné avec du bruit pourrait être #fcff09 a

rouge/vert=0.988

rouge/bleu=28

vert/bleu=28.33

le rouge et le vert sont encore assez proches et tous deux beaucoup plus élevés que le bleu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X