以编程方式将颜色从加载的位图逐像素交换为红色、绿色、蓝色或灰色

2024-03-30

在这里下载源代码:http://www.eyeClaxton.com/download/delphi/ColorSwap.zip http://www.eyeClaxton.com/download/delphi/ColorSwap.zip

是的,我想将“主要是蓝色”的东西转换为“主要是绿色的”。

我想获取原始位图(浅蓝色)并将颜色(逐像素)更改为红色、绿色、蓝色和灰色等价关系。为了理解我的意思,我提供了源代码和屏幕截图。任何帮助将不胜感激。如果需要更多信息,请随时询问。

如果您可以看一下下面的代码,我正在寻求三个函数的帮助。函数“RGBToRed、RGBToGreen 和 RGBToRed”我似乎无法想出正确的公式。

unit MainUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TMainFrm = class(TForm)
    Panel1: TPanel;
    Label1: TLabel;
    Panel2: TPanel;
    Label2: TLabel;
    Button1: TButton;
    BeforeImage1: TImage;
    AfterImage1: TImage;
    RadioGroup1: TRadioGroup;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainFrm: TMainFrm;

implementation

{$R *.DFM}
function RGBToGray(RGBColor: TColor): TColor;
var
  Gray: Byte;
begin
  Gray := Round(
    (0.90 * GetRValue(RGBColor)) +
    (0.88 * GetGValue(RGBColor)) +
    (0.33 * GetBValue(RGBColor)));

  Result := RGB(Gray, Gray, Gray);
end;

function RGBToRed(RGBColor: TColor): TColor;
var
  Red: Byte;
begin
  // Not sure of the algorithm for this color
  Result := RGB(Red, Red, Red);
end;

function RGBToGreen(RGBColor: TColor): TColor;
var
  Green: Byte;
begin
  // Not sure of the algorithm for this color
  Result := RGB(Green, Green, Green);
end;

function RGBToBlue(RGBColor: TColor): TColor;
var
  Blue: Byte;
begin
  // Not sure of the algorithm for this color
  Result := RGB(Blue, Blue, Blue);
end;

procedure TMainFrm.FormCreate(Sender: TObject);
begin
  BeforeImage1.Picture.LoadFromFile('Images\RightCenter.bmp');
end;

procedure TMainFrm.Button1Click(Sender: TObject);
var
  Bitmap: TBitmap;
  I, X: Integer;
  Color: Integer;
begin
  Bitmap := TBitmap.Create;
  try
    Bitmap.LoadFromFile('Images\RightCenter.bmp');

    for X := 0 to Bitmap.Height do
    begin
      for I := 0 to Bitmap.Width do
      begin
        Color := ColorToRGB(Bitmap.Canvas.Pixels[I, X]);

        case Color of
          $00000000: ;   // Skip any Color Here!
        else
          case RadioGroup1.ItemIndex of
            0: Bitmap.Canvas.Pixels[I, X] := RGBToBlue(Color);
            1: Bitmap.Canvas.Pixels[I, X] := RGBToRed(Color);
            2: Bitmap.Canvas.Pixels[I, X] := RGBToGreen(Color);
            3: Bitmap.Canvas.Pixels[I, X] := RGBToGray(Color);
          end;
        end;
      end;
    end;
    AfterImage1.Picture.Graphic := Bitmap;
  finally
    Bitmap.Free;
  end;
end;

end.

好吧,我很抱歉没有说清楚。我正在尝试获取位图(蓝色)并将蓝色像素替换为另一种颜色。就像下面的镜头一样。


我不知道你想实现什么目标。首先,这个问题与什么有关系等价关系 https://en.wikipedia.org/wiki/Equivalence_relation?

其次,代码

function RGBToRed(RGBColor: TColor): TColor;
var
  Red: Byte;
begin
  // Not sure of the algorithm for this color
  Result := RGB(Red, Red, Red);
end;

毫无意义。返回值未定义。这RGB函数采用 0 到 255 范围内的红色、绿色和蓝色强度,并返回TColor拥有这些组件。例如,RGB(255, 0, 0)是纯红色,即255红、0绿、0蓝。然而,在上面的代码中,Red没有初始化,所以Result可以是任何灰色(取决于什么Red恰好是)。 [而且,正如您可能知道的那样,如果您将等量的红色、绿色和蓝色混合在一起,就会得到灰色。] 例如,Red当你运行应用程序时,可能碰巧是 45,然后结果将是灰色RGB(45, 45, 45)。下次可能是163。

也许你想要一个接受a的函数TColor并返回它的红色分量?然后GetRValue会做的,而且 - 当然 - 还有GetGValue and GetBValue.

或者,也许您想从给定的颜色创建灰色TColor,就像使用 Photoshop 从彩色图像创建灰度图像时所做的那样。那么,如果Color is the TColor,合适的灰度值为

grey := (GetRValue(Color) + GetGValue(Color) + GetBValue(Color)) div 3;

还有其他方法可以做到这一点(导致灰度图像略有不同,但这是最简单(也是最快)的)。 (例如,您可以将颜色从 RGB 转换为 HSV 或 HSL,然后将饱和度设置为零。)

Update

我想我明白你想做什么。也许您想提取红色、绿色和蓝色通道。也就是说,你想要变换每个像素RGB(R, G, B) to RGB(R, 0, 0)在红色的情况下。如果这是你想做的,那么你应该这样做

function RGBToRed(RGBColor: TColor): TColor;
begin
  Result := RGB(GetRValue(RGBColor), 0, 0);
end;

对于其他组件也类似,即

function RGBToGreen(RGBColor: TColor): TColor;
begin
  Result := RGB(0, GetGValue(RGBColor), 0);
end;

and

function RGBToBlue(RGBColor: TColor): TColor;
begin
  Result := RGB(0, 0, GetBValue(RGBColor));
end;

或者可能

或者您可能只想将图像设为灰度,然后将其“着色”为红色(或绿色或蓝色)。那么你需要重型机械。理论上,您希望替换其中的每个像素HSV(h, s, v) to HSV(0, s, v)在红色的情况下,HSV(120, s, v)在绿色的情况下,并且HSV(240, s, v)在蓝色的情况下。或者,也许您还希望设置饱和度s to 1.

我使用以下程序在 RGB 和 HSV 之间进行转换:

function RGBToHSV(const Color: TRGB): THSV;
var
  cmax, cmin, cdiff: real;
begin
  cmax := MaxComponent(Color);
  cmin := MinComponent(Color);
  cdiff := cmax - cmin;

  with Color, result do
  begin

    // Hue
    if cmax = cmin then
      hsvHue := 0
    else if cmax = rgbRed then
      hsvHue := (60 * (rgbGreen - rgbBlue) / cdiff)
    else if cmax = rgbGreen then
      hsvHue := (60 * (rgbBlue - rgbRed) / cdiff) + 120
    else
      hsvHue := (60 * (rgbRed - rgbGreen) / cdiff) + 240;

    hsvHue := Fix360(hsvHue);

    // Saturation
    if cmax = 0 then
      hsvSaturation := 0
    else
      hsvSaturation := 1 - cmin / cmax;

    // Value
    hsvValue := cmax;

  end;

end;

and

function HSVToRGB(const Color: THSV): TRGB;
var
  hi: integer;
  f, q, p, t: real;
begin

  with Color do
  begin

    hi := floor(hsvHue / 60) mod 6;
    f := hsvHue / 60 - floor(hsvHue / 60);
    p := hsvValue * (1 - hsvSaturation);
    q := hsvValue * (1 - f * hsvSaturation);
    t := hsvValue * (1 - (1 - f) * hsvSaturation);

    case hi of
      0: result := RGB(hsvValue, t, p);
      1: result := RGB(q, hsvValue, p);
      2: result := RGB(p, hsvValue, t);
      3: result := RGB(p, q, hsvValue);
      4: result := RGB(t, p, hsvValue);
      5: result := RGB(hsvValue, p, q);
    end;

  end;

end;

where

type
  TRGB = record
    rgbRed,            // red intensity between 0 and 1
    rgbGreen,          // green intensity between 0 and 1
    rgbBlue: double;   // blue intensity between 0 and 1
  end;

  THSV = record
    hsvHue,            // hue angle between 0 and 360
    hsvSaturation,     // saturation between 0 (grey) and 1 (full colour)
    hsvValue: double;  // value between 0 (dark) and 1 ("normal")
  end;

在绿色的情况下,最终结果将是这样的

在第一种情况下(色调固定为 120)并且

在后一种情况下(色调固定为 120,饱和度固定为 1)。

或者,可能

即使经过编辑,你的问题也很模糊。您想要将“主要是蓝色”的内容转换为“主要是绿色”的内容。但有一千种方法可以做到这一点!当然,一个很简单的方法就是将蓝绿通道互换,即替换RGB(r, g, b) with RGB(r, b, g),或者明确地,

function SwapBlueGreen(Color: TColor): TColor;
begin
  result := RGB(GetRValue(Color), GetBValue(Color), GetGValue(Color));
end;

然后你会得到类似的东西

红色和绿色通道已交换。请注意,红棍现在是绿色的,绿草现在是红色的。白色的东西仍然是白色的。

Finally

欢迎来到像素图操作的世界!有很多简单而有趣的事情可以做。我的更多例子:https://english.rejbrand.se/algosim/manual/pmproc/pmproc.html https://english.rejbrand.se/algosim/manual/pmproc/pmproc.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以编程方式将颜色从加载的位图逐像素交换为红色、绿色、蓝色或灰色 的相关文章

  • Delphi应用程序窗口z顺序和MainFormOnTaskBar属性

    我正在维护一个最初用 Delphi 7 编写并移植到 Delphi XE 的应用程序 使用 Windows 7 我们遇到了一些问题 例如模态窗口出现在主窗口下方 以及最终无法与程序交互 因为用户需要与模态窗体交互 而这是不可能的 因为它位于
  • Delphi 2010 - 从 XML 文档解码 Base64 编码图像

    我正在尝试从应用程序中的 XML 文档解码 base64 编码的 EMF 图像并将其呈现在屏幕上 但是 它似乎从未出现 如果我将 XML 文档中的数据复制 粘贴到 Notepad 中并使用Base64 Decode选项并将文件另存为 emf
  • 对象的引用计数

    在我的代码中 我使用一个小的数据存储类 它是在不同的地方创建的 为了避免内存泄漏并简化事情 我想使用引用计数 所以我这样做了 type TFileInfo class TInterfacedObject IInterface 并删除了我对
  • 画布:尝试使用回收的位图错误

    我是一个相当新的程序员 所以任何建议将不胜感激 我有一个类 每次调用它时都会在循环中运行 AsyncTask AsyncTask 看起来像这样 public class LoadImageTask extends AsyncTask
  • 如何在iOS的Delphi程序中使用IPv6协议

    我尝试在我的移动程序中使用 IPv6 协议 我的服务器位于 NAT 后面的 LAN 内 在服务器上我使用IP端口3000 我已经组织了从路由器端口 45500 到服务器端口 3000 的虚拟服务器 端口转发 在服务器上 我运行 ipconf
  • 如何从该 JAVA 文件中提取 Delphi 类以与 Android 一起使用?

    我的Delphi XE7项目需要与FTDI FT311 Android 配件芯片 http www ftdichip com Products ICs FT311D html 他们帮助提供了一个 Android 演示 其中包括他们的 JAV
  • 加载位图图像至特定尺寸

    我正在尝试使用 allegro 将位图加载到特定大小 al crate bitmap x y 创建特定大小的位图 al load bitmap filename 加载我需要的图像 但为其原始大小 我需要将位图加载到我设置的大小 有任何想法吗
  • Pygame - 使用 SurfArray 将某种颜色的像素重新着色为另一种颜色(数组切片问题)

    我正在尝试为游戏制作调色板交换功能 并且正在尝试找到一种将某种颜色的像素颜色更改为另一种颜色的方法 我已经能够使用我在教程中找到的这个函数使所有像素具有相同的颜色 def color surface self surface red gre
  • JPEG 中的颜色配置文件检测

    我希望能够检测 JPEG 中是否存在颜色配置文件 需要明确的是 我对实际进行颜色校正或用它们做任何其他事情不感兴趣 我做了一些调查 但找不到任何明确的信息来源 到目前为止我所知道的是 里面有一个颜色配置信息XMP块 XMP 块位于0xFFE
  • 返回条件格式化单元格内部颜色的函数

    我想要一个返回条件格式单元格颜色索引值的函数 它用于检查一行中的多个单元格 如果它们使用条件格式突出显示 则需要执行操作 检查单元格中是否有颜色比创建覆盖条件的组合条件公式更简单所有细胞的 或者说我是这么想的 尽管代码在消息框中有效 但下面
  • 改变字符串颜色

    好的 这是我上一个问题的延续 但我有代码 private void btnTrans Click object sender EventArgs e var abrvStr inputBx Text foreach var kvp in d
  • R 颜色 - 许多独特的颜色仍然很漂亮

    我很好奇你是否有一些关于 R 中颜色酿造的技巧 对于许多独特的颜色 在某种程度上图形仍然好看 我需要相当数量的独特颜色 至少 24 种 可能需要更多 50 种 用于堆叠区域图 所以不是热图 渐变颜色不起作用 我发现了 viridis 它的调
  • Delphi 7 - 处理表单中嵌入框架的 MouseWheel 事件?

    你好 我有一个表格 里面有几个框架 对于某些框架 我希望滚动内容 或至少处理鼠标滚轮事件 我已经尝试过以下方法 只需为每个帧分配一个 OnMouseWheel 事件处理程序 重写父窗体的 MouseWheel 事件 procedure TF
  • Delphi Prism 中 TStringList 的替代品。

    我正在将用 Delphi 2007 Net 编写的应用程序迁移到 Delphi Prism 哪个是替换 TStringList 和 TStrings 类的最佳选择 提前致谢 Bye 只需使用 NET 框架中内置的 List 类型 或者字符串
  • D2010编译行数差异

    构建项目时 有两个地方会报告源代码行数 在编译进度对话框中 项目下 信息 在 Delphi 2007 中 对于我们正在构建的项目 这两个数字是相同的 在 Delphi 2010 中 这两个数字截然不同 1st 计数多出 100 万行或 40
  • 如何将枚举类型放入字符串列表中?

    这行代码 ShowMessage GetEnumName TypeInfo TAlign 1 返回 alTop 当我想使用字符串变量 TAlign 而不是TAlign时 如何将枚举类型的所有值放入字符串列表中 就像是 ShowMessage
  • 如何从灰度字节缓冲区图像创建位图?

    我正在尝试使用新的 Android 人脸检测移动视觉 API 来处理帧图像 所以我创建了自定义检测器来获取帧并尝试调用 getBitmap 方法 但它为空 所以我访问了帧的灰度数据 有没有办法从它或类似的图像持有者类创建位图 public
  • 以编程方式生成渐变?

    给定 2 个 RGB 颜色和一个矩形区域 我想在颜色之间生成基本的线性渐变 我进行了快速搜索 我唯一能找到的是这个博客条目 http jtauber com blog 2008 05 18 creating gradients progra
  • GDI 函数 BitBlt 和 StretchBlt 在 Win32 中是否硬件加速?

    我似乎无法通过搜索得到明确的答案 Win32 blitting 操作是否硬件加速 GDI 而不是 GDI 我不知道这些函数如何与图形驱动程序交互 是否有任何函数调用来验证此功能 例如 GetCaps 对于特定的图形设备 win32图形设备
  • 在 Android 的 Recycler View 中的文本视图背景上生成并设置随机颜色

    I am Trying to Generate Random Colors and set the Random color as background of Text View Just Like in GMail app The Tex

随机推荐

  • 如何忽略 Web 浏览器中的脚本错误

    当我关闭使用网络浏览器的应用程序时会发生什么 以下网址使用flash播放器 一切正常 此错误在应用程序关闭时显示 我该如何忽略它 我知道为时已晚 但我觉得我对这个问题有一个聪明的答案 使用这个 它对我来说很有效 webBrowser Scr
  • 多重处理:类型错误:“int”对象不可迭代

    我正在使用multiprocessingPython 3 中的模块 但由于某种原因 它不断抛出TypeError int object is not iterable当我运行程序时 这就是我所做的 def main i global url
  • mod_wsgi 无法连接 WSGI 守护进程

    我正在使用 Easy apache 4 mod wsgi 和 Python 3 5 当我在服务器中调用 Django 项目时 出现以下错误 13 Permission denied mod wsgi pid 24223 Unable to
  • 平移多个 Y 轴之一以获取高图

    我是 highchart javascript 的新手 而且我没有样品来展示它 但我见过图表有两个 Y 轴 左轴和右轴 我可以上下拖动一个轴而不影响另一个轴 该图表可能包含一些系列数据 我见过构建的插件 http www highchart
  • 非常快的无限循环,不阻塞 I/O

    有没有更快的替代方案window requestAnimationFrame 对于不阻塞 I O 的无限循环 我在循环中所做的事情与动画无关 所以我不在乎下一帧何时准备好 并且我已经读过window requestAnimationFram
  • intellij IDEA 中每个模块的不同存储库

    我不确定如何为 IDEA 项目中的每个不同模块选择不同的 git 存储库 我没有看到任何选项 所有 git 选项似乎只与一个 git 存储库相关 有没有办法区分它们 所以 全部在同一个项目内 Module A gt repo A Modul
  • android apache poi-ooxml 导致构建错误 'app:transformClassesWithDesugarForDebug'

    我的应用程序需要实现 Excel 创建和下载 我使用 Apache POI 的 HSSFWorkbook 来实现该功能 应用程序成功创建了所需的 Excel xls 输出 但是 如果我在 gradle 中包含 apache poi ooxm
  • 我想要一个提交按钮 该按钮提交的值与按钮 上显示的值不同 和
  • 如何在 Linux 上安全地、事务性地替换文件?

    我能想到的替换文件内容的最天真 最糟糕的方法是 f open file txt w f write stuff f close 显然 如果该操作在关闭之前的某个时刻失败 您将丢失原始文件的内容 而不一定完成新内容 那么 什么是完全正确的方法
  • Chef deploy_resource 私有存储库、ssh 部署密钥和 ssh_wrapper

    我在让我的厨师食谱克隆私人仓库时遇到了很多麻烦 好吧 我昨天还可以用 但是在 清理 我的 Vagrant 盒子六次之后 我把它弄坏了 正如你可能猜到的那样 我是一名厨师新手 按照此处的deploy resource指南 我创建了我的depl
  • 检查 NSNumber 是否为分数

    检查是否存在的最佳方法是什么NSNumber是分数吗 NumberIsFraction 0 NO NumberIsFraction 0 5 YES NumberIsFraction 1 0 NO 在边境案件处理和绩效方面 最佳 避免转换为具
  • MongoDB 作为时间序列数据库

    我正在尝试使用 mongodb 作为时间序列数据库 并且想知道是否有人可以建议如何最好地针对该场景进行设置 时间序列数据与股票价格历史非常相似 我收集了来自不同机器的各种传感器的数据 有数十亿个时间戳的值 我想问以下问题 最好来自数据库而不
  • 如何在命名类别中声明私有属性?

    我知道可以通过将类的私有属性放入实现中声明的类的未命名类别中来声明类的私有属性 m 该类的文件 那是not我想做的事 我正在处理一个类的命名类别 该类别为该类添加了一些功能 对于此功能 在我的类别中使用私有属性会对我有很大帮助 因此实现此功
  • 如何修复 C# 中的“使用未分配的局部变量”[重复]

    这个问题在这里已经有答案了 我是 C 新手 我最后的编程语言是 C 我不断收到 Use of unassigned local variable average 这average与之相关的是average 10 using System u
  • Android HttpUrlConnection EOFException

    我想知道 Android 上的 HttpUrlConnection 和 POST 请求是否存在已知问题 我们正在经历间歇性的从 Android 客户端发出 POST 请求时出现 EOFExceptions 重试相同的请求最终会成功 这是堆栈
  • 将 ruby​​ .gem 文件放在哪里以便 Shoes.setup 可以找到它们?

    关于鞋子中的宝石支持 人们提出了很多问题 但没有人回答将它们放在哪里 我在 Windows XP 上有 Shoes Raisins 1134 并且我已经下载dbi 0 4 1 gem我正在尝试让以下内容发挥作用 Shoes setup do
  • 从 Mongo 获取 BinData UUID 作为字符串

    我目前有一些 id 作为 UUID 存储在 Mongo 中 处理所需 他们像这样被返回 id new BinData 3 JliB6gIMRuSphAD2KmhzgQ 将此值转换为字符串以进行调试的简单方法是什么 需要明确的是 应用程序可以
  • 使用 SMOTE 对图像数据进行过采样

    我正在使用 CNN 进行二元分类 数据不平衡 其中正医学图像 负医学图像 0 4 0 6 所以我想在训练前使用SMOTE对正医学图像数据进行过采样 但是 数据的维度是 4D 761 64 64 3 这会导致错误 Found array wi
  • 如何在 Django 中强制用户注销?

    在我的 Django 应用程序中 在某些条件下 我希望能够强制用户通过用户名注销 不一定是当前登录的用户 而是另一个用户 因此 我认为请求方法没有任何有关我要注销的用户的会话信息 我熟悉 django auth 和 auth 注销方法 但需
  • 以编程方式将颜色从加载的位图逐像素交换为红色、绿色、蓝色或灰色

    在这里下载源代码 http www eyeClaxton com download delphi ColorSwap zip http www eyeClaxton com download delphi ColorSwap zip 是的