简体   繁体   English

Android Renderscript-在Renderscript中旋转YUV数据

[英]Android Renderscript - Rotate YUV data in Renderscript

Based on the discussion I had at Camera2 api Imageformat.yuv_420_888 results on rotated image , I wanted to know how to adjust the lookup done via rsGetElementAt_uchar methods so that the YUV data is rotated by 90 degree. 基于我在Camera2 api Imageformat.yuv_420_888旋转图像结果上的讨论,我想知道如何调整通过rsGetElementAt_uchar方法完成的查找,以便将YUV数据旋转90度。 I also have a project like the HdrViewfinder provided by Google. 我也有一个类似Google提供的HdrViewfinder的项目。 The problem is that the output is in landscape because the output surface used as target surface is connected to the yuv allocation which does not care if the device is in landscape or portrait mode. 问题在于输出是横向的,因为用作目标表面的输出表面已连接到yuv分配,而yuv分配并不关心设备是横向还是纵向模式。 But I want to adjust the code so that it is in portrait mode. 但是我想调整代码,使其处于纵向模式。 Therefore, I took a custom YUVToRGBA renderscript but I do not know what to change to rotate the output. 因此,我采用了自定义的YUVToRGBA渲染脚本,但不知道要更改哪些内容以旋转输出。 Can somebody help me to adjust the following custom YUVtoRGBA script by 90 degree because I want to use the output in portrait mode: 有人可以帮我将以下自定义YUVtoRGBA脚本调整90度,因为我想在纵向模式下使用输出:

// Needed directive for RS to work
#pragma version(1)

// The java_package_name directive needs to use your Activity's package path
#pragma rs java_package_name(net.hydex11.cameracaptureexample)

rs_allocation inputAllocation;

int wIn, hIn;
int numTotalPixels;

// Function to invoke before applying conversion
void setInputImageSize(int _w, int _h)
{
    wIn = _w;
    hIn = _h;
    numTotalPixels = wIn * hIn;
}

// Kernel that converts a YUV element to a RGBA one
uchar4 __attribute__((kernel)) convert(uint32_t x, uint32_t y)
{

    // YUV 4:2:0 planar image, with 8 bit Y samples, followed by
    // interleaved V/U plane with 8bit 2x2 subsampled chroma samples
    int baseIdx = x + y * wIn;
    int baseUYIndex = numTotalPixels + (y >> 1) * wIn + (x & 0xfffffe);

    uchar _y = rsGetElementAt_uchar(inputAllocation, baseIdx);
    uchar _u = rsGetElementAt_uchar(inputAllocation, baseUYIndex);
    uchar _v = rsGetElementAt_uchar(inputAllocation, baseUYIndex + 1);
    _y = _y < 16 ? 16 : _y;

    short Y = ((short)_y) - 16;
    short U = ((short)_u) - 128;
    short V = ((short)_v) - 128;

    uchar4 out;
    out.r = (uchar) clamp((float)(
        (Y * 298 + V * 409 + 128) >> 8), 0.f, 255.f);   
    out.g = (uchar) clamp((float)(
        (Y * 298 - U * 100 - V * 208 + 128) >> 8), 0.f, 255.f); 
    out.b = (uchar) clamp((float)(
        (Y * 298 + U * 516 + 128) >> 8), 0.f, 255.f); // 
    out.a = 255;

    return out;
}

I have found that custom script at https://bitbucket.org/cmaster11/rsbookexamples/src/tip/CameraCaptureExample/app/src/main/rs/customYUVToRGBAConverter.fs . 我在https://bitbucket.org/cmaster11/rsbookexamples/src/tip/CameraCaptureExample/app/src/main/rs/customYUVToRGBAConverter.fs中找到了自定义脚本。

Here someone has put the Java code to rotate YUV data. 在这里,有人放置了Java代码来旋转YUV数据。 But I want to do it in Renderscript since that is faster. 但我想在Renderscript中执行此操作,因为这样做速度更快。

Any help would be great. 任何帮助都会很棒。

best regards, 最好的祝福,

I'm assuming you want the output to be in RGBA, as in your conversion script. 我假设您希望输出像在转换脚本中一样是RGBA。 You should be able to use an approach like that used in this answer ; 您应该能够使用此答案中所使用的方法; that is, simply modify the x and y coordinates as the first step in the convert kernel: 也就是说,只需简单地将x和y坐标修改为转换内核的第一步即可:

//Rotate 90 deg clockwise during the conversion
uchar4 __attribute__((kernel)) convert(uint32_t inX, uint32_t inY)
{
    uint32_t x = wIn - 1 - inY;
    uint32_t y = inX;

    //...rest of the function

Note the changes to the parameter names. 注意对参数名称的更改。

This presumes you have set up the output dimensions correctly (see linked answer). 假设您已经正确设置了输出尺寸(请参阅链接的答案)。 A 270 degree rotation can be accomplished in a similar way. 270度旋转可以类似的方式完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM