Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firemonkey (FMX) bitmap and colours

Assume I have a small bitmap in Firemonkey (say 32x24 pixels). So I put a TImage onto a form and in the constructor there is this 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;

This draws a nice diagonal line on blackground.

What I want to do is now parse the bitmap to determine the pixels affected by the line draw. If I do a basic pixel by pixel check using:

  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]]));

the output onto my Memo is:

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

so it's interpreting and "blurring"? my line as the colours (represented by c above) are not equal to claYellow ($FFFF00). If I draw a horizontal or vertical line, the effect is the same. If I change my stroke thickness to 2 and draw a non-diagonal line it draws in claYellow but it covers 2 pixels.

So how can I determine the "true" pixels I've drawn on. In the above sample I would (could) look for $FFE7E700 but how do I know to look for that value (given that if I drew the line in a different colour, that value would be different). I tried to see if there's a consistent "difference" between the colour I drew with and the actual colour rendered but couldn't locate one.

Thanks

like image 572
Jason Avatar asked May 15 '12 00:05

Jason


2 Answers

FMX use antialiazing for drawing. If you would like draw line without blur effect you should use special function for pixel alignment:

  • TCanvas.AlignToPixel
  • TCanvas.AlignToPixelVertically
  • TCanvas.AlignToPixelHorizontally

This functions automatically calculate pixel position for drawing without blur.

Thank you

like image 198
Yaroslav Brovin Avatar answered Nov 07 '22 10:11

Yaroslav Brovin


The colors in the example are anti-aliased, meaning they're part the color you set, and part the background color. The precise ratio is based on many considerations done behind the scenes.

Not familiar with FireMonkey(or delphi), so I can't tell you if there's a way around it, but if you want to know where a certain color lands what you could do is test the ratios between RGB values, that's assuming you draw only one line on a black background(otherwise, the ratios must be a range to catch pixels with large amounts of noise)

example: yellow(#ffff00)

red/green=1

red/blue=green/blue=#inf(or if you want, 255/1=255)

a sampled pixel could be #fcfc00 maintaining the ratios

a sampled pixel with noise could be #fcff09 has

red/green=0.988

red/blue=28

green/blue=28.33

red and green are still pretty close and both much higher than blue.

like image 30
biaxynte Avatar answered Nov 07 '22 09:11

biaxynte