读取控制台调色板的 RGB 值
Reading the RGB values of the console color palette
肉
在 C 或 C++ 中,有没有办法直接读取调色板 RGB 值?特别有趣的是 xterm(和其他(用于定义多达 256 种终端颜色的扩展颜色空间。
土豆
这方面的例子是,我想定义自己的颜色(使用 ANSI 转义序列,如 e]4;3;rgb:cc/78/33e\
或直接在 c 中(,但我需要在重新定义用户颜色之前保存它们(万一他们已经重新定义了他们的颜色(,以便我可以在我的程序完成时恢复它们。用户设置不好。
现在,我的目标是使用 ANSI 转义序列以客户端方式执行此操作。但是由于我找不到如何去除颜色,因此我开始考虑在 c 或 c++ 中执行此操作。
该解决方案将被编写为具有本机扩展(基本上是嵌入式 c 或 c ++ 代码(的 ruby gem,我的目标是获得一个跨平台的解决方案,即使主要目标是 OS X,其次是 Linux 环境......
索斯
从最初的实验开始,我已经到了可以为调色板中的代码点定义任何颜色的地步。我还可以轻松恢复默认的系统颜色(因为它们是 ANSI 标准(。我已经在ANSI转义码中寻找一种方法来做到这一点,但没有找到。我认为这保存在内存中的某个地方,如果有任何方法可以找到位置,阅读颜色应该很容易......
甜点
总结到目前为止评论中的信息:
看起来唯一能始终如一地做到这一点的方法就是以不同的颜色打印 █ 个字符的屏幕并抓取其中的颜色。由于这个项目应该是跨平台的三个主要操作系统,并且由于Linux目前有3个显示管理器在用户使用中,而Windows有两个(7和8(,我只能想象那将是:)
所以我的"解决方案"™是只破坏用户的颜色(如果他们有系统默认值以外的任何东西......这,让我们面对这是非常罕见的(。我将提供一个设置文件,用户可以告诉插件如果他们对系统默认值不满意,应该恢复什么颜色。务实而无聊,但它让我再次继续:)
[编辑 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
}
使用 xterm(以及一些相似的(,您可以使用转义序列来获取调色板。 这记录在 XTerm 控制序列中:
OSC
Ps ;PtST
设置文本参数。 某些控制序列返回信息:
Ps = 4 ;c ;规范 ⇒ 将颜色编号 c 更改为规范指定的颜色。
如果给出的是"?">而不是名称或 RGB 规范,xterm以相同形式的控制序列进行回复,该可用于设置相应的颜色。 因为不止一对色号和规格可以一对给出控制序列,XTERM可以做出多个回复。
这样做可能会很慢。 xterm 提供了用于在堆栈上操作调色板的转义序列:
CSI
pm# P
将当前动态调色板和 ANSI 调色板颜色推送到堆栈上(XTPUSHCOLORS(,xterm。 参数(范围为 1 的整数通过 10,因为默认 0 将推送(可用于将调色板存储到堆栈中,而无需推送。
CSI
Pm
# Q
用于设置动态调色板和 ANSI 调色板颜色的弹出堆栈(XTPOPCOLORS(,xterm。 参数(范围为 1 的整数到 10,因为默认的 0 会弹出(可用于从堆栈中恢复调色板而不弹出。
iTerm2 和 Windows 终端的更改日志表明它们支持这些 xterm 功能。
/* Hi -- I think this C code will reveal all that you need to do all that you asked. Best wishes...*/
/*--------------------------------------------------------------------------
CONSOLE_LEGACY_PALETTE.C
Code by Greg Spears
Created 2022.10.22 and released into the public domain.
Tested, use at your own risk.
---------------------------------------------------------------------------*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
/* This is what the palette used to be before it was updated by Microsoft in 2017.*/
BYTE legacy_palette[16][3] = {
{0,0,0 },
{0,0,128},
{0,128,0},
{0,128,128},
{128,0,0},
{128,0,128},
{128,128,0},
{192,192,192},
{128,128,128},
{0,0,255},
{0,255,0},
{0,255,255},
{255,0,0},
{255,0,255},
{255,255,0},
{255,255,255}
};
/* Used for displaying the color palette by printf()*/
static char *szTextColors[] = {
"BLACK",
"BLUE",
"GREEN",
"CYAN",
"RED",
"MAGENTA",
"BROWN",
"LIGHTGRAY",
"DARKGRAY",
"LIGHTBLUE",
"LIGHTGREEN",
"LIGHTCYAN",
"LIGHTRED",
"LIGHTMAGENTA",
"YELLOW",
"WHITE"
};
/*--------------------------------------------------------------------------
set_legacy_palette()
DATE: REASON:
2022.10.22 - Created
Params: none
Returns: TRUE if the console palette updates successfully. FALSE if not.
---------------------------------------------------------------------------*/
int set_legacy_palette(void)
{
CONSOLE_SCREEN_BUFFER_INFOEX csbix;
int iii;
HANDLE hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
if(!hConOut)
{
printf("set_legacy_palette(): bad handle: hConOut");
return FALSE;
}
/* Use GetConsoleScreenBufferInfoEx() to get the console palette*/
csbix.cbSize = sizeof(csbix);
if(!GetConsoleScreenBufferInfoEx(hConOut, &csbix))
{
printf("GetConsoleScreenBufferInfoEx() failed!");
return FALSE;
}
printf("printing color palette: --------------------------n");
for (iii = 0; iii < 16; iii++)
printf("ColorTable[%d] = t%-12s [%3d,%3d,%3d]n", iii, szTextColors[iii],
GetRValue(csbix.ColorTable[iii]),
GetGValue(csbix.ColorTable[iii]),
GetBValue(csbix.ColorTable[iii]));
printf("--------------------------------------------------n");
/* Fill the palette strcuture with legacy RGB values*/
for(iii = 0; iii < 16; iii++)
csbix.ColorTable[iii] =
RGB(legacy_palette[iii][0], legacy_palette[iii][1], legacy_palette[iii][2]);
/* use SetConsoleScreenBufferInfoEx() to send the updated palette to the OS.
*/
if (!SetConsoleScreenBufferInfoEx(hConOut, &csbix))
{
printf("set_legacy_palette(): SetConsoleScreenBufferInfoEx() failed!");
return FALSE;
}
return TRUE;
}
- 使用FFMPEG将RGB图像序列保存到.mp4时出现问题
- 将RGB图像保存为PPM格式
- 在 C++ 中将 RGB 更改为灰度
- Qt中的RGB图像处理
- 在C++中查找像素 RGB 数据的最快方法是什么?
- 无法获取要在 OpenGL ES2 中显示的 RGB 纹理
- 如何将 MJPEG 解码为原始 RGB(或 YUV)数据
- 我们可以将阈值应用于色彩空间模型的单个组件(如 RGB 和 LAB)吗?
- 如何使用 C++将 2D RGB 数组转换为 dds 文件?
- 在RAW图像中提取RGB通道值的库或方法
- C++GDI+ 选择调色板
- 将Kinect v2帧速率(rgb、深度、骨架)设置为每秒25帧
- Qmage:如何将灰色图像转换为RGB热图
- 使用范围(OpenCV)脱粒RGB图像
- 如何将RGB像素缓冲区转换为IRandomAccessStream^
- (C++)(Visual Studio) 将高斯模糊滤镜应用于 RGB 中的灰度图像
- #Define , RGB colors for NeoPIxel
- 根据 C++ 中生成的随机数的值生成 Html RGB 值
- 用 c++ 将函数 RGB 写入 HSL
- 读取控制台调色板的 RGB 值