代码之家  ›  专栏  ›  技术社区  ›  Newbyte

如何在C中获取GdkRGBA结构的十六进制字符串表示?

  •  1
  • Newbyte  · 技术社区  · 1 年前

    我有一个程序,可以从配置文件中读取十六进制字符串表示形式,并将其转换为 a GdkRGBA struct from Gdk ,使用 gtk_color_dialog_button_set_rgba () 将其设置为GtkColorDialogButton的默认颜色,然后监听用户对上述按钮的更改。

    在用户更改时,我想将所选值写回配置文件,以便在程序启动时保持不变,出于传统兼容性的原因,我需要它是十六进制字符串表示(配置文件是 ~/.Xresources ,因此它需要与许多现有程序兼容)。然而,尽管Gdk提供了 gdk_rgba_parse () 函数将颜色的十六进制字符串表示解析为GdkRGBA结构,但我找不到任何相反的方法,即将GdkRGBB结构转换为十六进制字符串表达。有 gdk_rgba_to_string () ,但它只返回格式为的字符串 rgb(r,g,b) 或 rgba(r,g,b,a) ,而我想要 #rrggbb .

    如何在C中获取GdkRGBA结构体值的十六进制字符串表示?

    1 回复  |  直到 1 年前
        1
  •  2
  •   John Bollinger    1 年前

    有 gdk_rgba_to_string() ,但它只返回rgb(r,g,b)或rgba(r,g,b,a)形式的字符串,而我想要#rrggbb。

    因此,解析返回的字符串 gdk_rgba_to_string() 并根据需要格式化结果。有很多方法可以实现这一点。例如,

        char *rgba_str = gdk_rgba_to_string(rgba);
    
        unsigned int r, g, b;
        // rgba_str has the form "rgb(r,g,b)" or "rgba(r,g,b,a)", where r, g, b, a are
        // decimal integers in the range 0 - 255.
        int fields = sscanf(rgba_str, "%*[^(](%u,%u,%u", &r, &g, &b);
    
        // the caller of gdk_rgba_to_string() is responsible for freeing the result
        free(rgba_str);
    
        if (fields < 3) {
            // handle malformed rgba_str ...
        }
    
        // if paranoid then validate that r, g, and b are within the expected range ...
    
        char result[8];
    
        sprintf(result, "#%02x%02x%02x", r, g, b);
    

    虽然[ s ] scanf 对于交互式输入可能会有问题,但对于您可以依赖的格式规则的输入,它会做得很好 gdk_rgba_to_string() 生产。

    或者,键入 GdkRGBA 是 documented ,并且它对您的代码不是不透明的。而不是通过 gdk_rgba_to_string() 的字符串表示形式,您可以直接读取结构成员,从 float 正确排列整数,并如上所述格式化结果。例如,

        unsigned int r, g, b;
    
        r = (unsigned int) (0.5 + rgba->red * 255);
        g = (unsigned int) (0.5 + rgba->green * 255);
        b = (unsigned int) (0.5 + rgba->blue * 255);
    
        char result[8];
    
        sprintf(result, "#%02x%02x%02x", r, g, b);
    

    这些转换来自 浮动 基于 GdkRGBA 证明颜色值在范围内的文档 0.0 - 1.0 ,包括在内,对于这些值,它们与Gdk本身执行的转换相匹配(感谢@IanAbatt)。通过将超出范围的值夹紧到该范围内,可以使其更安全。

    我注意到,这种转换有一个不幸的特性,即映射到两个端点的值的范围都是映射到其他整数值的范围的一半大小,但你有点坚持Gdk的做事方式。这不应该仅仅是在整数和浮点之间来回切换,但相对于在浮点空间中操纵的颜色的所有颜色值分配相同的大小范围,它有一些次要的影响。