更改位图的HUE但保留背景颜色?

时间:2012-05-16 16:06:23

标签: delphi delphi-xe

我一直在尝试使用EFG网站上的Change HUE/Saturation示例:http://www.efg2.com/Lab/Library/Delphi/Graphics/Color.htm

enter image description here

我想使用该示例中找到的技术来更改某些位图的颜色值(用于TImage)。我面临一个问题,那就是TImages具有透明的位图;我不希望背景颜色改变其HUE,而只是改变实际的图像数据。

拍摄我们可以使用的样本图像(尽管可以使用任何具有透明度的图像):

enter image description here

  • 从顶部的链接下载Change HUE/Saturation演示。
  • 现在将上面的按钮图像加载到ImageOriginal。
  • 将Delta饱和度设置为1。
  • 运行项目。

一些输出结果:

enter image description here enter image description here

我想在这里发生的是保持原始背景颜色(由最左下角的像素定义)并仅调整图像其余部分的色调。因此,输出结果实际上看起来像这样(在Paint.NET中编辑):

enter image description here enter image description here

允许我使用另一个样本图像进行测试,其中包含更多图像数据:

enter image description here

与之前的第一个图像样本一样,结果可能类似于:

enter image description here enter image description here

当我想要的结果应该如此:

enter image description here enter image description here

我有一个想法是在HUE改变之后,用原始颜色替换左下方的颜色,但我不确定这是否是正确的方法,即使它是我不知道如何将颜色X替换为另一种颜色。 (图形和数学超出我的范围。)

例如,如果我在Mickey耳朵上画了两个蓝色圆圈(蓝色是左下角最左边的原始透明色),并且还涂上了他的眼睛:

enter image description here

再次更改HUE可能如下所示:

enter image description here

实际上它应该是这样的:

enter image description here

简单地说我想改变图像的HUE,无论是通过EFG演示使用的方法还是其他解决方案。当HUE更改时,不应更改由最左侧像素定义的透明颜色,这应保持与样本图像中所示的相同。

如何在保留背景颜色的同时更改位图的HUE?

2 个答案:

答案 0 :(得分:5)

您引用的代码遍历图像上的所有像素以更改色调/饱和度。您可以修改代码,以便在像素具有特定颜色时不会干扰:

PROCEDURE TFormChangeHS.UpdateBitmap;
    ..
    S              :  TReal;
    V              :  TReal;

    FixColor: TRGBTriple;                            // New variable
BEGIN
  DeltaSaturation := SpinEditDeltaSaturation.Value;
  NewHue := TrackBarHue.Position;

  Bitmap := TBitmap.Create;
  TRY
    Bitmap.Width  := ImageOriginal.Width;
    Bitmap.Height := ImageOriginal.Height;
    Bitmap.PixelFormat := ImageOriginal.Picture.Bitmap.PixelFormat;
    ASSERT(Bitmap.PixelFormat = pf24bit);

    // save bottom left color
    FixColor := PRGBTripleArray(
                  ImageOriginal.Picture.Bitmap.ScanLine[Bitmap.Height - 1])^[0];
    //--

    FOR j := 0 TO Bitmap.Height-1 DO
    BEGIN
      RowIn  := ImageOriginal.Picture.Bitmap.Scanline[j];
      RowOut := Bitmap.Scanline[j];
      FOR i := 0 TO Bitmap.Width-1 DO
      BEGIN
        WITH RowIn[i] DO
        BEGIN

          // copy the color to target and continue with next iteration
          if (RowIn[i].rgbtBlue = FixColor.rgbtBlue) and
              (RowIn[i].rgbtGreen = FixColor.rgbtGreen) and
              (RowIn[i].rgbtRed = FixColor.rgbtRed) then begin
            RowOut[i] := FixColor;
            Continue;
          end;
          //--

          // convert pixel coordinates to HSV
          RGBtoHSV(rgbtRed, rgbtGreen, rgbtBlue, H, S, V);
        END;
        ..
        ..


输出:

enter code here

答案 1 :(得分:2)

理论上,你可以举例:

首先,你必须确定背景是什么......(可能选择像delphi这样的特定像素的颜色......)

然后,使用此背景颜色,您可以根据此颜色创建蒙版......

您复制了图片...应用色调......

使用掩码合并2位图...