直接看未使用模板的例子: 处理一个 a和RGB 混合的参数为不混合rgba值, 其实为QT中带Premultiplied的像素转为普通像素,处理函数如下:
int Process(imagetype type, unsigned int* pixelhead)
{
int R = 0, G = 0, B = 0, A = 0;
switch (type)
{
case eRGBA32:
R = 0;
G = 1;
B = 2;
A = 3;
break;
case eARGB32:
R = 3;
G = 2;
B = 1;
A = 0;
break;
case eBGRA32:
R = 2;
G = 1;
B = 0;
A = 3;
break;
case eABGR32:
R = 1;
G = 2;
B = 3;
A = 0;
break;
default:
break;
}
unsigned char* pixel = (unsigned char*)pixelhead;
char a = (char)pixel[A];
char r = (char)pixel[R];
char g = (char)pixel[G];
char b = (char)pixel[B];
if (a == 0)
{
return 0;
}
pixel[R] = r * 255 / a;
pixel[G] = g * 255 / a;
pixel[B] = b * 255 / a;
return 0;
}
模板的写法有点笨拙,看似代码量更大, 可能我写的比较拙, 代码如下:
#include "stdafx.h"
#include <vector>
#include <algorithm>
enum imagetype
{
eRGBA32,
eARGB32,
eBGRA32,
eABGR32
};
//这里需要写个基类,不然后面调用将无法new, 因为模板参数不确定编译不过
class BaseProcess {
public:
virtual int Process(unsigned int * pixelhead)
{
return 0;
}
};
template<imagetype T, int R, int G, int B, int A>
class DecodePremultipliedColor :public BaseProcess
{
public:
DecodePremultipliedColor() {}
virtual int Process(unsigned int * pixelhead)
{
unsigned char* pixel = (unsigned char*)pixelhead;
char a = (char)pixel[A];
char r = (char)pixel[R];
char g = (char)pixel[G];
char b = (char)pixel[B];
if (a == 0)
{
return 0;
}
pixel[R] = r * 255 / a;
pixel[G] = g * 255 / a;
pixel[B] = b * 255 / a;
return 0;
}
};
//定义这几种枚举类型的实力,不然无法调用
typedef DecodePremultipliedColor<eRGBA32, 0, 1, 2, 3> RGBA32Premultiplied;
typedef DecodePremultipliedColor<eABGR32, 3, 2, 1, 0> ABGR32Premultiplied;
typedef DecodePremultipliedColor<eBGRA32, 2, 1, 0, 3> BGRA32Premultiplied;
typedef DecodePremultipliedColor<eARGB32, 1, 2, 3, 0> ARGB32Premultiplied;
int main()
{
//模板调用
imagetype type =eRGBA;
BaseProcess * pProcess = 0;
switch (type)
{
case eRGBA32:pProcess = new RGBA32Premultiplied(); break;
case eARGB32:pProcess = new ARGB32Premultiplied(); break;
case eBGRA32:pProcess = new BGRA32Premultiplied(); break;
case eABGR32:pProcess = new ABGR32Premultiplied(); break;
default:
break;
}
unsigned int g = 0xff343433;
pProcess->Process(&g);
//直接函数调用
Process(type, &g);
}
要是能直接推导第一个参数就好,可惜没找到写法. 另外两种写的代码量竟然都是44行,不存在一个代码量多少问题