C++ 图像数据翻转代码 (水平翻转 垂直翻转 对角线翻转)

直接上代码

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);
    }
}

垂直翻转比较特殊,不管多少通道,代码也可以通用的
对角线翻转就是 水平翻转 + 垂直翻转

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值