【问题标题】:Base 10 number to 16 bit colour in C#在 C# 中以 10 为基数到 16 位颜色
【发布时间】:2014-03-12 21:53:42
【问题描述】:

我试图将 16 位颜色深度的 65,536 种颜色中的每一种都表示为以 10 为底的整数,但我遇到了麻烦。

基本上我需要将一个基数为 10 的数字转换为一个 Color 对象,该对象表示 16 位光谱中的该颜色。我认为基地在这里很重要,但我无法决定去哪个基地。

【问题讨论】:

  • 你需要使用十六进制以外的东西的原因是什么?
  • 你认为一个整数不是以 10 为底或以 16 为底的理由是什么?如果有的话,它是基数 2。
  • @GolezTrol:我认为这些都不是。从技术上讲,数量没有“基础”,仅用于表示。
  • 这就是我说“如果有的话”的原因。但我想当你看到一个非常低的级别(即查看你的 RAM 中的触发器)时,base 2 实际上非常接近。二进制在计算机语言中非常流行是有原因的。 ;)

标签: c# math colors base


【解决方案1】:

16 位色彩空间使用 5 位用于红色通道、6 位用于绿色通道和 5 位用于蓝色通道。您可以使用按位运算提取每个通道的值。

int color = /* your 16 bit value here */

int red = color & 31;
int green = (color >> 5) & 63;
int blue = color >> 11;

要转换回来,请使用

int color = red | green << 5 | blue << 11;

【讨论】:

  • +1 先换档,再申请&amp;。我早该想到的。
【解决方案2】:

Color 对象包含 ARGB 中的颜色。 A 代表 Alpha,您现在不需要它。其他是红色、绿色和蓝色的值。它们中的每一个都是一个 8 位的值。 ARG 和 B 一起形成 32 位颜色。

16 位颜色一开始就很奇怪,因为红色和蓝色有 5 位,而绿色有 6 位。

要将这些转换为 8 位,您可以对它们进行位移(或相乘)。

int input = Your16BitColorValue;
var color = new Color;

color.R = input & 0x1F; /* Isolate 5 least significant bits */
color.G = (input & 0x7E0) >> 5; /* Isolate 6 middle bits and shift them 5 right */
color.B = (input & 0xF800) >> 11; /* Isolate left 5 bits and shift them right */

这是非常准确的。例如,对于绿色,一个 6 位数字,最高值(所有 6 位设置)是 63。位设置的下半部分导致 7(最大值的 1/9)。当您移动这两个位置以转换为 8 位数字时,您会得到 28,这也是 255 的 1/9。如果您尝试其他几个示例,您会发现每个示例都非常接近。最大的舍入误差,你会在频谱的末端找到。例如 63,它是 16 位中最亮的绿色,将导致 252,几乎是 32 位中最亮的绿色,但不完全是。

要解决这个问题,您可以使用一个因子,如下所示:

Value32 = Value16 * 255 / Max16Value

其中 Max16Value 为 31(红色和蓝色)或 63(绿色)。例如:

Color.B = ((input >> 11) & 0x1F) * 255 / 31;

这样,输入中的 31 红色实际上会在 32 位颜色中产生 255 的红色,这在这两种情况下都是最亮的值。

【讨论】:

  • @Transmission 添加了一些关于不同计算的内容,这可能会稍微好一些,尽管您可能看不到差异。无论如何,我希望它不会让它变得更加混乱。 ;)
  • 我知道了,非常感谢您花时间发布如此详细的答案!
猜你喜欢
  • 2012-11-23
  • 1970-01-01
  • 1970-01-01
  • 2021-02-09
  • 1970-01-01
  • 1970-01-01
  • 2013-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多