将yuv数据旋转90度 180度 270度

这两天在做yuv数据推流。我这里是从camera2获取的image转yuv(nv21)数据,推流上去发现图像逆时针旋转了90度,网上一大堆都是对预览方向调整的。然后找了好多对yuv数据旋转的算法。

链接: https://stackoverflow.com/questions/14167976/rotate-an-yuv-byte-array-on-android.
这里面介绍了关于yuv数据旋转,很有帮助!!!牛逼!
里面主要是介绍这三个方法

public static byte[] rotateYUV420Degree90(byte[] data, int imageWidth, int imageHeight) {
    byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
    // Rotate the Y luma
    int i = 0;
    for (int x = 0; x < imageWidth; x++) {
        for (int y = imageHeight - 1; y >= 0; y--) {
            yuv[i] = data[y * imageWidth + x];
            i++;
        }
    }
    // Rotate the U and V color components
    i = imageWidth * imageHeight * 3 / 2 - 1;
    for (int x = imageWidth - 1; x > 0; x = x - 2) {
        for (int y = 0; y < imageHeight / 2; y++) {
            yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
            i--;
            yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth)
                    + (x - 1)];
            i--;
        }
    }
    return yuv;
}

private static byte[] rotateYUV420Degree180(byte[] data, int imageWidth, int imageHeight) {
    byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
    int i = 0;
    int count = 0;
    for (i = imageWidth * imageHeight - 1; i >= 0; i--) {
        yuv[count] = data[i];
        count++;
    }
    i = imageWidth * imageHeight * 3 / 2 - 1;
    for (i = imageWidth * imageHeight * 3 / 2 - 1; i >= imageWidth
            * imageHeight; i -= 2) {
        yuv[count++] = data[i - 1];
        yuv[count++] = data[i];
    }
    return yuv;
}

public static byte[] rotateYUV420Degree270(byte[] data, int imageWidth,
                                     int imageHeight) {
    byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
    int nWidth = 0, nHeight = 0;
    int wh = 0;
    int uvHeight = 0;
    if (imageWidth != nWidth || imageHeight != nHeight) {
        nWidth = imageWidth;
        nHeight = imageHeight;
        wh = imageWidth * imageHeight;
        uvHeight = imageHeight >> 1;// uvHeight = height / 2
    }
    // ??Y
    int k = 0;
    for (int i = 0; i < imageWidth; i++) {
        int nPos = 0;
        for (int j = 0; j < imageHeight; j++) {
            yuv[k] = data[nPos + i];
            k++;
            nPos += imageWidth;
        }
    }
    for (int i = 0; i < imageWidth; i += 2) {
        int nPos = wh;
        for (int j = 0; j < uvHeight; j++) {
            yuv[k] = data[nPos + i];
            yuv[k + 1] = data[nPos + i + 1];
            k += 2;
            nPos += imageWidth;
        }
    }
    return rotateYUV420Degree180(yuv, imageWidth, imageHeight);
}

以及下面这个很多人分享的图片旋转90度
在这里插入图片描述
我全都试了一遍,全都出现花屏四重影的情况,评论里都说好用,我想不能够啊,搞了一天差点顶不住,最后终于在论坛找到一个大佬的评论,瞬间豁然开朗
在这里插入图片描述
对,就是这么简单。你在使用旋转后的yuv数据传入宽高的时候要对调一下
比如我这个
在这里插入图片描述
改成
在这里插入图片描述
完美解决。下班

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
以下是将 YUV422 平面格式数据旋转 270 的 C 代码实现: ```c void rotate_yuv422p270(unsigned char *src, unsigned char *dst, int width, int height) { int i, j, k, l; int src_y_index, src_uv_index, dst_y_index, dst_uv_index; unsigned char *src_y, *src_u, *src_v, *dst_y, *dst_u, *dst_v; unsigned char y1, y2, u, v; // 计算旋转后图像的宽高 int dst_width = height; int dst_height = width; // 计算 Y、U、V 平面的大小 int src_y_size = width * height; int src_uv_size = width * height / 2; int dst_y_size = dst_width * dst_height; int dst_uv_size = dst_width * dst_height / 2; // 分配内存 src_y = src; src_u = src + src_y_size; src_v = src_u + src_uv_size; dst_y = dst; dst_u = dst + dst_y_size; dst_v = dst_u + dst_uv_size; // 旋转 Y 平面 for (i = 0; i < height; i++) { for (j = 0; j < width; j += 2) { src_y_index = i * width + j; dst_y_index = (dst_width - j / 2 - 1) * dst_width + i; y1 = src_y[src_y_index]; y2 = src_y[src_y_index + 1]; dst_y[dst_y_index] = y1; dst_y[dst_y_index - dst_width] = y2; } } // 旋转 U、V 平面 for (i = 0; i < height / 2; i++) { for (j = 0; j < width; j += 2) { src_uv_index = i * width + j; dst_uv_index = (dst_width - j / 2 - 1) * dst_width / 2 + i / 2; u = src_u[src_uv_index]; v = src_v[src_uv_index]; dst_u[dst_uv_index] = u; dst_v[dst_uv_index] = v; } } } ``` 这段代码中,首先计算旋转后图像的宽高和 YUV422 平面格式的大小,然后将 Y、U、V 平面的指针分别指向输入和输出数据中对应的位置。 接下来,通过双重循环逐个像素地将输入数据中的像素复制到输出数据中,并且根据旋转方向调整像素的位置和顺序。具体来说,对于 Y 平面,每次处理两个像素,将第一个像素复制到输出数据的最后一列、第一行中,将第二个像素复制到输出数据的倒数第二列、第二行中。对于 U、V 平面,每次处理一个像素,将其复制到输出数据中对应的位置上。 最后,输出数据中的 YUV422 平面格式数据就是旋转后的结果。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值