Firemonkey (FMX) 位图和颜色

Posted

技术标签:

【中文标题】Firemonkey (FMX) 位图和颜色【英文标题】:Firemonkey (FMX) bitmap and colours 【发布时间】:2012-05-22 12:01:05 【问题描述】:

假设我在 Firemonkey 中有一个小位图(比如 32x24 像素)。所以我把一个 TImage 放到一个表单上,在构造函数中有这个代码:

  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;

这在黑地上画了一条漂亮的对角线。

我现在要做的是解析位图以确定受线条绘制影响的像素。如果我使用以下方法进行基本的逐像素检查:

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

我备忘录上的输出是:

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

所以它是在解释和“模糊”?我的线作为颜色(由上面的 c 表示)不等于 claYellow ($FFFF00)。如果我画一条水平线或垂直线,效果是一样的。如果我将笔画粗细更改为 2 并绘制一条非对角线,它会在 claYellow 中绘制,但它覆盖 2 个像素。

那么我如何确定我绘制的“真实”像素。在上面的示例中,我将(可以)查找 $FFE7E700 但我怎么知道要查找该值(假设我以不同的颜色绘制线,该值会有所不同)。我试图查看我绘制的颜色和实际渲染的颜色之间是否存在一致的“差异”,但找不到。

谢谢

【问题讨论】:

不是你的问题的答案......但另一个有趣的question 我不知道 FireMonkey,但这听起来与普通的抗锯齿差不多。 这与 FireMonkey 无关。它完全依赖于底层图形系统(GDI+、D2D、OpenGL)。 如果你使用“PointF(1.5,1.5), PointF(10.5,10.5)”画线,可能没有抗锯齿,它会按照你期望的方式工作。 @Giel - 不幸的是,它并没有太大的不同。它只是返回了一个不同的值(在本例中为 $FFEBEB00)。 【参考方案1】:

FMX 使用抗锯齿进行绘图。如果您想绘制没有模糊效果的线条,您应该使用特殊功能进行像素对齐:

TCanvas.AlignToPixel TCanvas.AlignToPixelVertically TCanvas.AlignToPixelHorizo​​ntally

此函数自动计算像素位置以进行无模糊绘制。

谢谢

【讨论】:

谢谢。我只是能够回到这个。您能否详细说明您的答案并说明如何在上述示例中使用这些功能。在任何地方都有关于这些功能的几乎 0 文档,而且我尝试过的内容并没有改变读取 - 即使我现在使用位图的 Map/Unmap。【参考方案2】:

示例中的颜色是抗锯齿的,这意味着它们是您设置的颜色的一部分,也是背景颜色的一部分。精确的比例是基于幕后所做的许多考虑。

不熟悉 FireMonkey(或 delphi),所以我无法告诉您是否有解决方法,但如果您想知道某种颜色的位置,您可以测试 RGB 值之间的比率,那就是假设你在黑色背景上只画了一条线(否则,比率必须是一个范围才能捕获具有大量噪声的像素)

示例: 黄色(#ffff00)

红/绿=1

red/blue=green/blue=#inf(或者如果你愿意,255/1=255)

一个采样像素可以是#fcfc00 保持比率

带有噪声的采样像素可能是#fcff09 有

红/绿=0.988

红/蓝=28

绿色/蓝色=28.33

红色和绿色仍然非常接近,并且都比蓝色高得多。

【讨论】:

以上是关于Firemonkey (FMX) 位图和颜色的主要内容,如果未能解决你的问题,请参考以下文章

DELPHI (VCL及FMX[Firemonkey])启动时的欢迎窗口实现代码

在 Firemonkey 组件中旋转时如何避免重复图像?

如何使用TBitmap的功能为FireMonkey和VCL工作?

[修正] Firemonkey 中英文混排折行问题(移动平台)

如何使用firemonkey在选定区域裁剪位图?

FMX:展平多个图像