【问题标题】:Reading the RGB values of the console color palette读取控制台调色板的 RGB 值
【发布时间】:2013-10-14 09:17:18
【问题描述】:

肉类

在 C 或 C++ 中有什么方法可以直接读取调色板的 RGB 值?特别有趣的是 xterm(和其他人)使用扩展颜色空间来定义多达 256 种终端颜色。

土豆

我想定义自己的颜色(使用 ANSI 转义序列,如\e]4;3;rgb:cc/78/33\e\\,或直接在 c 中)但我需要在重新定义用户颜色之前保存它们(在不太可能的情况下他们已经重新定义了他们的颜色),以便我可以在我的程序完成时恢复它们。破坏用户设置不好。

现在我的目标是使用 ANSI 转义序列以客户端方式执行此操作。但由于我找不到你如何获得颜色,我开始考虑用 c 或 c++ 来代替。

该解决方案将被编写为带有原生扩展(基本上是嵌入式 c 或 c++ 代码)的 ruby​​ gem,我的目标是获得一个跨平台解决方案,即使主要目标是 OS X,其次是 Linux 环境。 .

从我最初的实验中,我已经可以为调色板中的代码点定义我想要的任何颜色。我还可以轻松恢复默认系统颜色(因为它们是 ANSI 标准)。我在 ANSI 转义码中寻找一种方法来实现这一点,但没有找到。我认为这是保存在某个地方的内存中,如果有任何方法可以找到位置,读取颜色应该很容易......

甜点

总结目前在cmets中的信息:

看起来唯一能始终如一地做到这一点的方法是用不同颜色打印一个包含 █ 个字符的屏幕,然后从中提取颜色。由于该项目应该是跨三个主要操作系统的跨平台,并且由于 Linux 目前在用户使用时有 3 个显示管理器,而 Windows 有两个(7 和 8)我只能想象几个小时和几个小时的乐趣会是:)

所以我的“解决方案”™ 只是破坏用户的颜色(如果他们有系统默认值以外的任何其他颜色......让我们面对这种情况非常罕见)。我将提供一个设置文件,用户可以告诉插件如果他们对系统默认设置不满意,应该恢复哪些颜色。务实而无聊,但它让我再次开始这样做:)

【问题讨论】:

  • 愚蠢的问题,但是你有没有四处寻找一些相关的问题? For example,这个讨论了关于获取区域或整个屏幕的解决方案的几种变体。我想知道使用 ::GetPixel 这样的东西是否适合你?
  • 我已经阅读了关于 SO 和 SuperUser 等的所有相关问题。这里的问题是您处于控制台上下文中,因此获取像素值可能不是一种选择,因为您不能依赖拥有图形环境。我真正想要的是一个转义序列,或者是一种直接访问内存中颜色表的方法。虽然不可能接缝:/

标签: c++ c console-application xterm ansi-colors


【解决方案1】:

[编辑 1] 抱歉,这不会导致解决方案,但对于其他人,我添加了 DAC 调色板 IO 访问权限

查看旧的 EGA/VGA 参考 ...

  • 您可以通过 I/O 访问调色板
  • 我认为是端口 0x03C8、0x03C9 十六进制。
  • 当然在现代操作系统中你无法访问它
  • 所以在 DOS-BOX 或其他任何地方尝试一下并保存原始调色板值,它们应该是相同的。

直接访问试试这个:

BYTE r,g,b,c=5; // R,G,B values are 6 bit only !!!
out 0x3C8,c;    // set color index to work with <0,255>
in  r,0x3C9;    // read color pallete for color c
in  g,0x3C9;    // not sure if it should be r,g,b 
in  b,0x3C9;    // or b,g,r ... i did not use it for too many years
out 0x3C8,c;    // set color index to work with <0,255>
out 0x3C9,r;    // write color pallete for color c
out 0x3C9,g;
out 0x3C9,b;

C/C++ 没有 in,out 操作,所以使用这个:

BYTE i,o;       // this must be local !!!
WORD port;      // this must be local !!!
asm {
    mov dx,port // in i,port
    in al,dx
    mov o,al

    mov dx,port // out port,o
    mov al,o
    out dx,al
    }

【讨论】:

  • 正如问题中所指出的,它是关于保留用户颜色,而不仅仅是恢复系统默认值。获取默认值的静态地图很容易:)
  • 通过对 EGA/VGA 的 IO 访问,您可以从大多数控制台通常运行的 256 色调色板中单独获取和设置任何颜色。唯一的问题是您是否有 IO 访问权限...
  • 附言。调色板存储在 gfx 卡上而不是 CPU 访问的内存空间中,因此这是您想要的内存访问......如果控制台不是文本模式,那么它仍然应该模拟 256 色 EGA/VGA 模式。如果不是,那么它不是真正的控制台,只是一些仿真,唯一的方法是前面提到的屏幕的 GetPixel(屏幕不是窗口!!!)。在这种情况下,只需写入 256 个不同颜色的字符并读取它们的字体颜色(由于抗锯齿需要添加一些过滤)
  • 我接受这是一种可行的方法 :) 在这种情况下,唯一的问题是我将其编写为 Ruby gem,然后 C/C++ 代码将被编译为本机延期。我必须在 OS X、Linux 和 Windows 上处理这个问题,并承诺会带来很多乐趣,试图让它在三个操作系统上运行,至少有 6 个不同的显示管理器 o_= 我真的希望有一个更规范的解决方案,但是它可能不存在(在这种情况下,我将在退出时通过恢复系统默认颜色来破坏用户设置:))。
  • 好吧,如果您所针对的所有平台中都没有 API,那么这可能是唯一的解决方案。很抱歉没有帮助。 PS。我发现我的旧 asm 和 pas 源的 IO 地址不在 0x3C8,colorix;然后在 r,0x3C9 中; g,0x3C9;在 b,0x3C9 中;用于调色板读取或与调色板集相同的输出。
猜你喜欢
  • 1970-01-01
  • 2021-11-07
  • 2013-06-25
  • 2014-02-04
  • 2012-03-19
  • 2011-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多