直接上代码
enum PixelFlip
{
__NoFlip = 0,
__Horizontally,
__Vertically,
__Diagonally,
};
enum PixelChannel
{
__U8 = 1, // 8 bit
__U24 = 3, // 8:8:8 bit
};
void flip(uint8_t *data, int width, int height, PixelFlip state, PixelChannel channel)
{
if( state == PixelFlip::__NoFlip ) {
return;
}
int cx = width / 2;
int cy = height / 2;
uint8_t *front = NULL;
uint8_t *back = NULL;
uint8_t d;
switch (state) {
case PixelFlip::__Horizontally: {
for(int i = 0; i < height; i ++) {
front = data + (width * i * channel);
back = data + (width * (i + 1) * channel - channel);
for(int j = 0; j < cx; j ++) {
for(int c = 0; c < channel; c ++) {
d = front[c];
front[c] = back[c];
back[c] = d;
}
front += channel;
back -= channel;
}
}
}
break;
case PixelFlip::__Vertically: {
front = data;
for(int i = 0; i < cy; i ++) {
back = data + (width * (height - i - 1) * channel);
for(int j = 0; j < width; j ++) {
for(int c = 0; c < channel; c ++) {
d = *front;
*front = *back;
*back = d;
front ++;
back ++;
}
}
}
}
break;
case PixelFlip::__Diagonally: {
front = data;
back = data + (width * height * channel - channel);
int count = width * height / 2;
for(int i = 0; i < count; i ++) {
for(int c = 0; c < channel; c ++) {
d = front[c];
front[c] = back[c];
back[c] = d;
}
front += channel;
back -= channel;
}
}
break;
default: break;
}
}
因为现在做的项目图像是单通道和三通道的,所以写的比较复杂
代码其实还可以优化
如果通道数为偶数,可以看下面的例子
typedef unsigned char U8;
typedef unsigned char U24;
typedef unsigned int U32;
void horizontally_u32(uint8_t *data, int width, int height)
{
int cx = width / 2;
U32 *u32 = reinterpret_cast<uint32_t *>(data);
U32 *front = NULL;
U32 *back = NULL;
U32 d;
for(int i = 0; i < height; i ++) {
front = u32 + (width * i);
back = u32 + (width * i + width - 1);
for(int j = 0; j < cx; j ++) {
d = *front;
*front = *back;
*back = d;
front ++;
back --;
}
}
}
void horizontally_u24(uint8_t *data, int width, int height)
{
const int channel = 3;
int cx = width / 2;
int offset;
U24 *front = NULL;
U24 *back = NULL;
U24 d;
for(int i = 0; i < height; i ++) {
offset = width * channel * i;
front = data + offset;
back = data + (offset + width * channel - channel);
for(int j = 0; j < cx; j ++) {
for(int c = 0; c < channel; c ++) {
d = front[c];
front[c] = back[c];
back[c] = d;
}
front += channel;
back -= channel;
}
front += (cx * channel + channel);
back += (cx * channel + width * channel);
}
}
void horizontally_u8(uint8_t *data, int width, int height)
{
int cx = width / 2;
U8 *front = NULL;
U8 *back = NULL;
U8 d;
for(int i = 0; i < height; i ++) {
front = data + (width * i);
back = data + (width * i + width - 1);
for(int j = 0; j < cx; j ++) {
d = *front;
*front = *back;
*back = d;
front ++;
back --;
}
front += cx + 1;
back += (cx + width);
}
}
垂直翻转比较特殊,不管多少通道,代码也可以通用的
对角线翻转就是 水平翻转 + 垂直翻转