c++ - 在原始类型模板特化之间转换

标签 c++ templates colors struct

我正在开发一个简单的图像编辑器,我需要能够在像素类型(例如 8 位 RGB 和 32 位 RGBA)之间进行转换。我设置来表示像素的是一个模板结构:

template<unsigned int bit_depth, PIXEL_FORMAT fmt> struct Pixel {};

PIXEL_FORMAT作为enum class .

目标是能够在处理图像时在不同像素格式之间自由转换。但是,如果我尝试像这样从 8 位 RGB 转换为 16 位 RGB:

    Pixel<16, PIXEL_FORMAT::RGB> convert_to_16rgb() {
        char red, grn, blu;
        red = ((color & RED_8_BIT) >> 5);
        grn = ((color & GRN_8_BIT) >> 2);
        blu = (color & BLU_8_BIT);

        red = ((red/7) * 31); //(red/(2^3)-1) * ((2^5)-1)
        grn = ((grn/7) * 63);
        blu = ((blu/3) * 31); //these are to maintain the ratio but bring up the actual value

        Pixel<16, PIXEL_FORMAT::RGB> _16rgb(red, grn, blu); //Pixel<16, RGB has a 3-uchar c'tor available, but it's down below

        return _16rgb;
    }

我收到一条错误消息,指出 Pixel<16, PIXEL_FORMAT::RGB>在声明之前被实例化。没问题,只需向前声明它(构造函数也是如此)。然后我得到一个错误,说它是一个部分结构,不能使用。

那么我将如何尝试在各种特化之间转换呢?在结构定义之外创建模板函数?不过,我需要专门针对每个组合,而如果我在每个专门化中定义两个转换,那么我可以简单地“链接”它们,从一个转换到下一个,直到达到我想要的结果(例如从 8 转换位 RGB 到 24 位 RGB 我可以定义 _8rgb -> _16rgb 转换,然后定义 _16rgb 到 _24rgb 转换,而不是在 Pixel<8, RGB> 内同时定义 _16rgb 和 _24rgb 转换)

应要求,small example .

最佳答案

由于 Pixel 的一个特化需要定义另一个以用于转换目的,因此您需要在实现转换算法之前定义所有这些特化。这可以通过推迟转换函数的定义来实现,如下所示,我编辑了一段从您提供的示例中取出的代码:

template<unsigned bit_depth, PIXEL_FORMAT fmt> struct Pixel {};

template<> struct Pixel<8, PIXEL_FORMAT::RGB> {
    unsigned char color;
    Pixel(unsigned char red, unsigned char green, unsigned char blue) {
        color = 0xFF & (((red << 5) & RED_3_3_2) & ((green << 2) & GRN_3_3_2) & (blue & BLU_3_3_2));
    }

    Pixel(unsigned char clr) { color = clr; }

    Pixel<16, PIXEL_FORMAT::RGB> convert_to_rgb16();
};

template<> struct Pixel<16, PIXEL_FORMAT::RGB> {
    unsigned short color;
    Pixel(unsigned char red, unsigned char green, unsigned char blue) {
        color = (0xFFFF & (((red << 11) & RED_5_6_5) & ((green << 5) & GRN_5_6_5) & (blue & BLU_5_6_5)));
    }
    Pixel(short clr) { color = clr; }
};

Pixel<16, PIXEL_FORMAT::RGB> Pixel<8, PIXEL_FORMAT::RGB>::convert_to_rgb16() {
    unsigned char red, grn, blu;
    red = ((color & RED_3_3_2) >> 5);
    grn = ((color & GRN_3_3_2) >> 2);
    blu = (color & BLU_3_3_2);

    red = ((red/7) * 31); //5
    grn = ((grn/7) * 63); //6
    blu = ((blu/3) * 31); //5

    Pixel<16, PIXEL_FORMAT::RGB> _16rgb(red, grn, blu);
    return _16rgb;
}

请注意,convert_to_rgb16 在 16 位像素的特化定义之后,在 8 位像素的特化之外定义。

关于c++ - 在原始类型模板特化之间转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18564098/

相关文章:

c++ - 用 C 或 C++ 扩展 Python 有什么好处?

c++ - 在我的程序主函数中输入结束时预期为 '}'

c++ - 指针未在 C++ 类中初始化

c++通过构造函数选择推断bool类模板参数

java - 安卓/Java : Determining if text color will blend in with the background?

c++ - 这是一种构造函数吗?

templates - 如何在Hugo中通过FilePath排序内容?

c++ - 如何模板化 C++ 构造函数以实现完美转发

颜色渐变的数学

c# - C#中不同颜色的表格