¿Cómo aplicar LUT de color a imágenes de mapa de bits para efectos de filtro en android?
Aquí tengo una pregunta sobre LUTs en android.
Mi pregunta es, tengo 4X4 LUTs, el uso de estos LUTs aplicar efecto de filtro para la imagen de mapa de bits en android. A continuación se muestra mi vínculo de archivo LUT de ejemplo. Ejemplo de link de enlace
- Cómo llenar el color en la imagen en el área en particular?
- ¿Cuándo (si es que) debería usar Bitmap.recycle ()?
- Android - ¿Cómo obtener o establecer (imprimir) DPI (puntos por pulgada) de archivo JPEG mientras se carga o se guarda mediante programación?
- Android Gauge Animation Pregunta
- Problemas de memoria en fragmentos que muestran imágenes
¿Es posible en android? Si es posible, por favor ayúdame a aplicar.
Gracias por adelantado.
- Error android.graphics.Canvas.throwIfRecycled when overlaying bitmaps
- ¿Por qué setImageBitmap no tiene efecto en ImageButton personalizado?
- Tamaño y tamaño de los mapas de bits de Android canvas
- Cómo blit () en android?
- Actualizar / cambiar el mapa de bits en caché utilizando Picasso y OkHttp
- Fuera de error de memoria que se ocupa de mapas de bits grandes y el ciclo de vida de actividad de Android
- Dibujo de mapa de bits de mosaico con alineación inferior
- Leer en JPG como RGB888 en Android
Estoy trabajando en una biblioteca LUT aplicador que facilita el uso de imágenes LUT en Android. Utiliza el algoritmo de abajo, pero me gustaría mejorarlo en el futuro para optimizar el uso de memoria. Ahora también adivina los ejes de color de la LUT: https://github.com/dntks/easyLUT/wiki
Su imagen LUT tiene la dimensión de color rojo-verde-azul en un orden diferente de lo que he estado acostumbrado a, por lo que tuve que cambiar el orden de cuando se obtiene el lutIndex (en getLutIndex()
). Por favor revise mi respuesta editada:
final static int X_DEPTH = 16; final static int Y_DEPTH = 16; //One little square has 16x16 pixels in it final static int ROW_DEPTH = 4; final static int COLUMN_DEPTH = 4; // the image consists of 4x4 little squares final static int COLOR_DISTORTION = 16; // 256*256*256 => 256 no distortion, 64*64*64 => 256 dividied by 4 = 64, 16x16x16 => 256 dividied by 16 = 16 private Bitmap applyLutToBitmap(Bitmap src, Bitmap lutBitmap) { int lutWidth = lutBitmap.getWidth(); int lutColors[] = new int[lutWidth * lutBitmap.getHeight()]; lutBitmap.getPixels(lutColors, 0, lutWidth, 0, 0, lutWidth, lutBitmap.getHeight()); int mWidth = src.getWidth(); int mHeight = src.getHeight(); int[] pix = new int[mWidth * mHeight]; src.getPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight); int R, G, B; for (int y = 0; y < mHeight; y++) for (int x = 0; x < mWidth; x++) { int index = y * mWidth + x; int r = ((pix[index] >> 16) & 0xff) / COLOR_DISTORTION; int g = ((pix[index] >> 8) & 0xff) / COLOR_DISTORTION; int b = (pix[index] & 0xff) / COLOR_DISTORTION; int lutIndex = getLutIndex(lutWidth, r, g, b); R = ((lutColors[lutIndex] >> 16) & 0xff); G = ((lutColors[lutIndex] >> 8) & 0xff); B = ((lutColors[lutIndex]) & 0xff); pix[index] = 0xff000000 | (R << 16) | (G << 8) | B; } Bitmap filteredBitmap = Bitmap.createBitmap(mWidth, mHeight, src.getConfig()); filteredBitmap.setPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight); return filteredBitmap; } //the magic happens here private int getLutIndex(int lutWidth, int redDepth, int greenDepth, int blueDepth) { int lutX = (greenDepth % ROW_DEPTH) * X_DEPTH + blueDepth; int lutY = (greenDepth / COLUMN_DEPTH) * Y_DEPTH + redDepth; return lutY * lutWidth + lutX; }
Esto es cómo procesar una imagen con ScriptIntrinsic3DLUT de RenderScript
import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Bundle; import android.renderscript.Allocation; import android.renderscript.Element; import android.renderscript.RenderScript; import android.renderscript.ScriptIntrinsic3DLUT; import android.renderscript.Type; import android.support.v7.app.AppCompatActivity; import android.widget.ImageView; public class MainActivity extends AppCompatActivity { ImageView imageView1; RenderScript mRs; Bitmap mBitmap; Bitmap mLutBitmap; ScriptIntrinsic3DLUT mScriptlut; Bitmap mOutputBitmap; Allocation mAllocIn; Allocation mAllocOut; Allocation mAllocCube; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView1 = (ImageView) findViewById(R.id.imageView); mRs = RenderScript.create(this); Background background = new Background(); background.execute(); } class Background extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { if (mRs == null) { mRs = RenderScript.create(MainActivity.this); } if (mBitmap == null) { mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bugs); mOutputBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig()); mAllocIn = Allocation.createFromBitmap(mRs, mBitmap); mAllocOut = Allocation.createFromBitmap(mRs, mOutputBitmap); } if (mLutBitmap == null) { mLutBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dawizfe); int w = mLutBitmap.getWidth(); int h = mLutBitmap.getHeight(); int redDim = w / 4; int greenDim = h / 4; int blueDim = 16; android.renderscript.Type.Builder tb = new Type.Builder(mRs, Element.U8_4(mRs)); tb.setX(redDim); tb.setY(greenDim); tb.setZ(blueDim); Type t = tb.create(); mAllocCube = Allocation.createTyped(mRs, t); int[] pixels = new int[w * h]; int[] lut = new int[w * h]; mLutBitmap.getPixels(pixels, 0, w, 0, 0, w, h); int i = 0; for (int r = 0; r < redDim; r++) { for (int g = 0; g < greenDim; g++) { for (int b = 0; b < blueDim; b++) { int gdown = g / 4; int gright = g % 4; lut[i] = pixels[b + r * w + gdown * w * redDim + gright * blueDim]; i++; } } } // This is an identity 3D LUT // i = 0; // for (int r = 0; r < redDim; r++) { // for (int g = 0; g < greenDim; g++) { // for (int b = 0; b < blueDim; b++) { // int bcol = (b * 255) / blueDim; // int gcol = (g * 255) / greenDim; // int rcol = (r * 255) / redDim; // lut[i] = bcol | (gcol << 8) | (rcol << 16); // i++; // } // } // } mAllocCube.copyFromUnchecked(lut); } if (mScriptlut == null) { mScriptlut = ScriptIntrinsic3DLUT.create(mRs, Element.U8_4(mRs)); } mScriptlut.setLUT(mAllocCube); mScriptlut.forEach(mAllocIn, mAllocOut); mAllocOut.copyTo(mOutputBitmap); return null; } @Override protected void onPostExecute(Void aVoid) { imageView1.setImageBitmap(mOutputBitmap); } } }
U puede pasar por esto, espero que le ayudará a obtener el proceso correcto.
Foto es el mapa de bits principal aquí.
MLut3D es el conjunto de imágenes LUT almacenadas en
RenderScript mRs; Bitmap mLutBitmap, mBitmap; ScriptIntrinsic3DLUT mScriptlut; Bitmap mOutputBitmap; Allocation mAllocIn; Allocation mAllocOut; Allocation mAllocCube; int mFilter = 0; mRs = RenderScript.create(yourActivity.this); public Bitmap filterapply() { int redDim, greenDim, blueDim; int w, h; int[] lut; if (mScriptlut == null) { mScriptlut = ScriptIntrinsic3DLUT.create(mRs, Element.U8_4(mRs)); } if (mBitmap == null) { mBitmap = photo; } mOutputBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig()); mAllocIn = Allocation.createFromBitmap(mRs, mBitmap); mAllocOut = Allocation.createFromBitmap(mRs, mOutputBitmap); // } mLutBitmap = BitmapFactory.decodeResource(getResources(), mLut3D[mFilter]); w = mLutBitmap.getWidth(); h = mLutBitmap.getHeight(); redDim = w / h; greenDim = redDim; blueDim = redDim; int[] pixels = new int[w * h]; lut = new int[w * h]; mLutBitmap.getPixels(pixels, 0, w, 0, 0, w, h); int i = 0; for (int r = 0; r < redDim; r++) { for (int g = 0; g < greenDim; g++) { int p = r + g * w; for (int b = 0; b < blueDim; b++) { lut[i++] = pixels[p + b * h]; } } } Type.Builder tb = new Type.Builder(mRs, Element.U8_4(mRs)); tb.setX(redDim).setY(greenDim).setZ(blueDim); Type t = tb.create(); mAllocCube = Allocation.createTyped(mRs, t); mAllocCube.copyFromUnchecked(lut); mScriptlut.setLUT(mAllocCube); mScriptlut.forEach(mAllocIn, mAllocOut); mAllocOut.copyTo(mOutputBitmap); return mOutputBitmap; }
Usted aumenta el valor del mFilter para conseguir el efecto diferente del filtro con diversas imágenes de LUT, usted tiene, la comprueban hacia fuera.
Usted puede ir a través de este enlace en github para obtener más ayuda, tengo la respuesta de aquí: – https://github.com/RenderScript/RsLutDemo
Espero que ayude
- Descripción de las fugas de memoria en una aplicación de Android
- AVD Emulator no muestra los botones de hardware