2

I'm trying to find a method, way or kind of algorithm to downsize YUV images to an specific width and height values without converting it into RGB, just manipulating the byte[] of my YUV image.

I just found another topics about this as Resize (downsize) YUV420sp image

I see that the way to achieve this is removing pixels, but I can just do it always using a factor of 4 because chroma pixels are shared between 4 luma pixels.

enter image description here

After researching I just achieve the next method, which rescale a YUV image four times smaller than the original image, but want I want to achieve is freely convert from a Width x Height resolution to a smaller one that I want, not a factor of 4. It is possible to achieve this in some way? I don't have problems in use Renderscript or any kind of libraries.

/**
     * Rescale a YUV image four times smaller than the original image for faster processing.
     *
     * @param data        Byte array of the original YUV image
     * @param imageWidth  Width in px of the original YUV image
     * @param imageHeight Height in px of the original YUV image
     * @return Byte array containing the downscaled YUV image
     */
    public static byte[] quadYuv420(byte[] data, int imageWidth, int imageHeight) {
        Log.v(TAG, "[quadYuv420] receiving image with " + imageWidth + "x" + imageHeight);
        long startingTime = System.currentTimeMillis();
        byte[] yuv = new byte[imageWidth / 8 * imageHeight / 8 * 3 / 2];
        // process Y component
        int i = 0;
        for (int y = 0; y < imageHeight; y += 8) {
            for (int x = 0; x < imageWidth; x += 8) {
                yuv[i] = data[y * imageWidth + x];
                i++;
            }
        }
        // process U and V color components
        for (int y = 0; y < imageHeight / 2; y += 8) {
            for (int x = 0; x < imageWidth; x += 16) {
                if (i < yuv.length) {
                    yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
                    i++;
                    yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x + 1)];
                    i++;
                }
            }
        }
        Log.v(TAG, "[quadYuv420] Rescaled YUV420 in " + (System.currentTimeMillis() - startingTime) + "ms");
        return yuv;
    }
halfer
  • 19,824
  • 17
  • 99
  • 186
Francisco Durdin Garcia
  • 12,540
  • 9
  • 53
  • 95

1 Answers1

4

Take a look at libyuv https://chromium.googlesource.com/libyuv/libyuv/

You may need to write a jni wrapper and convert the yuv to planar using the convert functions included in the project - https://chromium.googlesource.com/libyuv/libyuv/+/master/include/libyuv/convert.h

anton
  • 136
  • 2
  • 1
    Thank you mate, it really helped me, now i'm fighting with the librar. Take a look to my new question to see if u can give me a hand: http://stackoverflow.com/questions/42960251/problems-when-scaling-a-yuv-image-using-libyuv-library – Francisco Durdin Garcia Mar 22 '17 at 19:36