Convertire la cornice di anteprima in bitmap

So che l'argomento era sul tavolo molte volte, ma non riesco a funzionare comunque … voglio salvare i fotogrammi di vista dall'anteprima in file jpeg. Sembra più o less (il codice è semplificato – senza ulteriore logica, exception ecc.) Come questo …

public void onPreviewFrame(byte[] data, Camera camera) { int width = camera.getParameters().getPreviewSize().width; int height = camera.getParameters().getPreviewSize().height; final int[] rgb = decodeYUV420SP(data, width, height); Bitmap bmp = Bitmap.createBitmap(rgb, width, height,Bitmap.Config.ARGB_8888); String filename="/sdcard/file" + (index++)+ ".jpg"; FileOutputStream out; out = new FileOutputStream(filename); bmp.compress(Bitmap.CompressFormat.JPEG, 90, out); out.flush(); out.close(); out=null; } 

Ecco uno dei methods che ho cercato di convertire i colors (da questa scheda credo)

  • Conversione a formato Dalvik non rioutput: Imansible eseguire la dex: java.nio.BufferOverflowException
  • Strategia di app Android per tenere traccia di una session di accesso
  • Android Picasso ImageView - Memoria eccezionale di MemoryLeak
  • La barra di stato della notifica di phonegap di android non mostra nulla
  • Prendi la schermata di SurfaceView
  • ArrayAdapter richiede che l'ID sia un errore TextView
  •  public int[] decodeYUV420SP( byte[] yuv420sp, int width, int height) { final int frameSize = width * height; int rgb[]=new int[width*height]; for (int j = 0, yp = 0; j < height; j++) { int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; for (int i = 0; i < width; i++, yp++) { int y = (0xff & ((int) yuv420sp[yp])) - 16; if (y < 0) y = 0; if ((i & 1) == 0) { v = (0xff & yuv420sp[uvp++]) - 128; u = (0xff & yuv420sp[uvp++]) - 128; } int y1192 = 1192 * y; int r = (y1192 + 1634 * v); int g = (y1192 - 833 * v - 400 * u); int b = (y1192 + 2066 * u); if (r < 0) r = 0; else if (r > 262143) r = 262143; if (g < 0) g = 0; else if (g > 262143) g = 262143; if (b < 0) b = 0; else if (b > 262143) b = 262143; rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); } } return rgb; } 

    Il problema è che l'image sembra sempre tre "immagini verdi" … io sono un nuovo utente quindi non posso pubblicarlo 🙁

    Non so se ha qualcosa a che fare con la dimensione o cosa ma sono bloccato … Puoi supportrmi con esso?

  • Riga colors alternativa di Android in ListView
  • Come leggere tutti i byte insieme via Bluetooth?
  • Usi gli stili di caratteri predefiniti in Android
  • Cambia l'icona del cassetto sul retro della freccia
  • Come submit i parametri JSON come richiesta di servizio Web in Android?
  • ADB non risponde. Puoi aspettare di più o uccidere manualmente il process "adb.exe" e fare clic su "Riavvia"
  • 5 Solutions collect form web for “Convertire la cornice di anteprima in bitmap”

    In alternativa, se avete bisogno di una bitmap per qualche ragione e / o vogliono farlo senza creare un file YUVi e compresso in JPEG, puoi utilizzare il pratico RenderScript 'ScriptIntrinsicYuvToRGB' (API 17+):

     @Override public void onPreviewFrame(byte[] data, Camera camera) { Bitmap bitmap = Bitmap.createBitmap(r.width(), r.height(), Bitmap.Config.ARGB_8888); Allocation bmData = renderScriptNV21ToRGBA888( mContext, r.width(), r.height(), data); bmData.copyTo(bitmap); } public Allocation renderScriptNV21ToRGBA888(Context context, int width, int height, byte[] nv21) { RenderScript rs = RenderScript.create(context); ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs)); Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(nv21.length); Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT); Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(width).setY(height); Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT); in.copyFrom(nv21); yuvToRgbIntrinsic.setInput(in); yuvToRgbIntrinsic.forEach(out); return out; } 

    Il semplice salvataggio di un jpeg è un task più facile della conversione a bitmap, senza bisogno di quel codice di decodifica YUV grazie alla class YuvImage .

     import android.graphics.YuvImage; @Override public void onPreviewFrame(byte[] data, Camera camera) { try { Camera.Parameters parameters = camera.getParameters(); Size size = parameters.getPreviewSize(); YuvImage image = new YuvImage(data, parameters.getPreviewFormat(), size.width, size.height, null); File file = new File(Environment.getExternalStorageDirectory(), "out.jpg"); FileOutputStream filecon = new FileOutputStream(file); image.compressToJpeg( new Rect(0, 0, image.getWidth(), image.getHeight()), 90, filecon); } catch (FileNotFoundException e) { Toast toast = Toast .makeText(getBaseContext(), e.getMessage(), 1000); toast.show(); } } 

    come ho scoperto la width e l'altezza letti da PreviewSize erano sbagliati … In altre parole la conversione è andata storto perché era basata su valori falsi. Dopo l'uso, un nuovo modo per impostare le impostazioni di anteprima (da esempio inviato da google) tutto funziona bene.

    EDIT:

    Ci dispiace per la risposta rapida sopra e per lungo tempo.

    Era tempo fa e non posso scavare il codice ora, ma penso di aver usato:

    http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getSupportedPreviewSizes ()

    e ha preso il primo elemento dall'elenco e impostato i valori

    http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setPreviewSize(int, int)

    ho memorizzato la width e l'altezza e l'ho usato per trasformare l'image.

    Non sa se fosse la soluzione migliore, ma ha funzionato.

    Se non mi sbaglio, desideri che la width e l'altezza dell'image siano decodificati, non la width e la dimensione dell'anteprima.

    Per evitare un'image JPEG degradata sull'output (ad es. Con interlacciatura di punti verdi / rossi), è necessario scorrere e chiudere FileOutputStream

     FileOutputStream filecon = new FileOutputStream(file); image.compressToJpeg( new Rect(0, 0, image.getWidth(), image.getHeight()), 90, filecon); filecon.flush(); filecon.close(); 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.