android rotation renderscript

android - ¿Puedo configurar las asignaciones de entrada y salida en Renderscript para que sean de diferentes tamaños/dimensiones?



rotation (1)

Fondo

Intento aprender Renderscript, así que quiero intentar hacer algunas operaciones simples en las que pienso.

El problema

Pensé en rotar un mapa de bits, que es algo que es bastante simple de administrar.

en C / C ++, es algo sencillo de hacer (buscar "jniRotateBitmapCw90"):

https://github.com/AndroidDeveloperLB/AndroidJniBitmapOperations/blob/master/JniBitmapOperationsLibrary/jni/JniBitmapOperationsLibrary.cpp

La cosa es que cuando pruebo esto en Renderscript, obtengo este error:

android.support.v8.renderscript.RSRuntimeException: ¡No coinciden las dimensiones entre los parámetros ain y aout!

Esto es lo que hago:

RS:

void rotate90CW(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) { // XY. ..X ... ... // ...>..Y>...>Y.. // ... ... .YX X.. out[...]=in[...] ... }

Java:

mRenderScript = RenderScript.create(this); mInBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample_photo); mOutBitmap = Bitmap.createBitmap(mInBitmap.getHeight(), mInBitmap.getWidth(), mInBitmap.getConfig()); final Allocation input = Allocation.createFromBitmap(mRenderScript, mInBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); final Allocation output = Allocation.createFromBitmap(mRenderScript, mOutBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); ScriptC_test script = new ScriptC_test(mRenderScript, getResources(), R.raw.test); ... script.forEach_rotate90CW(input, output); output.copyTo(mOutBitmap);

Incluso cuando configuro ambas asignaciones para que tengan el mismo tamaño (mapa de bits cuadrado), y simplemente configuro la salida como entrada:

out[width * y + x] = in[width * y+x];

  • entonces lo que obtengo es un mapa de bits con agujeros ... ¿Cómo es posible?

Esto es lo que obtengo:

Las preguntas

  1. ¿Esto significa que no puedo hacer este tipo de operación?

  2. ¿Significa que no puedo usar asignaciones de varios tamaños / dimensiones?

  3. ¿Es posible superar este problema (y todavía usar Renderscript, por supuesto)? ¿Si es así, cómo? ¿Tal vez podría agregar una variable de matriz dentro del lado RS, y establecer la asignación a ella, en su lugar?

  4. ¿Por qué tengo agujeros en el mapa de bits, para el caso de una entrada y salida cuadradas?

EDITAR: Este es mi código actual:

RS

rs_allocation *in;

atributo uchar4 ((kernel)) rotate90CW (uint32_t x, uint32_t y) {// XY. ..X ... ... // ...> .. Y> ...> Y .. // ... ... .YX X .. uchar4 curIn = rsGetElementAt_uchar4 (in, 0, 0) ; retorno curIn; // solo para probar ...}

Java:

mRenderScript = RenderScript.create(this); mInBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample_photo); mOutBitmap = Bitmap.createBitmap(mInBitmap.getHeight(), mInBitmap.getWidth(), mInBitmap.getConfig()); final Allocation input = Allocation.createFromBitmap(mRenderScript, mInBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); final Allocation output = Allocation.createFromBitmap(mRenderScript, mOutBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); ScriptC_test script = new ScriptC_test(mRenderScript, getResources(), R.raw.test); script.bind_in(input); script.forEach_rotate90CW(output); output.copyTo(mOutBitmap); mImageView.setImageBitmap(mOutBitmap);


Aquí va:

  1. ¿Esto significa que no puedo hacer este tipo de operación?

No en realidad no. Solo tienes que crear cosas correctamente.

  1. ¿Significa que no puedo usar asignaciones de varios tamaños / dimensiones?

No, pero significa que no puede usar asignaciones de diferentes tamaños en la forma en que actualmente está haciendo las cosas. El mecanismo predeterminado de kernel in / out espera que los tamaños de entrada y salida coincidan para que pueda iterar sobre todos los elementos correctamente. Si necesita algo diferente, depende de usted administrarlo. Más sobre eso a continuación.

  1. ¿Es posible superar estos problemas ... cómo?

La solución más fácil sería crear una asignación para la entrada y vincularla a la instancia de renderscript en lugar de pasarla como parámetro. Entonces su RS solo necesitaría una asignación de salida (y su kernel solo tomaría salida, xey). Desde allí puede determinar qué coordenada dentro de la asignación de entrada desea y colocarla directamente en la ubicación de salida:

int inX = ...; int inY = ...; uchar4 curIn = rsGetElementAt_uchar4(inAlloc, inX, inY); *out = curIn;

  1. ¿Por qué tengo agujeros en el mapa de bits, para el caso de una entrada y salida cuadradas?

Es porque no puede usar los parámetros xey para compensar la asignación de entrada y salida. Esos parámetros de entrada / salida ya están apuntando a la ubicación correcta (misma) tanto en la entrada como en la salida. La indexación que estás haciendo es innecesaria y no es realmente compatible. Cada vez que se llama a su kernel, se solicita una ubicación de 1 elemento dentro de la asignación. Esta es la razón por la que los tamaños de entrada y salida deben ser los mismos cuando se proporcionan como parámetros.