直接看未使用模板的例子: 處理一個 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行,不存在一個代碼量多少問題