2016-07-22 18 views
1

Ich versuche also, C++ - Code von einem Kollegen zu portieren, der Bilddaten über einen seriellen Bluetoth-Port ergreift (ich benutze ein Android-Telefon). Aus den Daten muss ich eine Bitmap generieren.BitmapFactory.decodeByteArray() gibt immer null zurück (manuell erstelltes Byte-Array)

Bevor ich den portierten Code getestet habe, habe ich diese Schnellfunktion an geschrieben, die ein reines rotes Rechteck erzeugt. BitmapFactory.decodeByteArray() schlägt jedoch immer fehl und wird mit einer Null-Bitmap zurückgegeben. Ich habe nach beiden möglichen Ausnahmen gesucht, die geworfen werden können und keiner wird geworfen.

byte[] pixelData = new byte[225*160*4]; 
       for(int i = 0; i < 225*160; i++) { 
        pixelData[i * 4 + 0] = (byte)255; 
        pixelData[i * 4 + 1] = (byte)255; 
        pixelData[i * 4 + 2] = (byte)0; 
        pixelData[i * 4 + 3] = (byte)0; 
       } 
       Bitmap image = null; 
       logBox.append("Creating bitmap from pixel data...\n"); 
       BitmapFactory.Options options = new BitmapFactory.Options(); 
       options.inPreferredConfig = Bitmap.Config.ARGB_8888; 
       options.outWidth = 225; 
       options.outHeight = 160; 

       try { 
        image = BitmapFactory.decodeByteArray(pixelData, 0, pixelData.length, options); 
       } catch (IllegalArgumentException e) { 
        logBox.append(e.toString() + '\n'); 
       } 
       //pixelData = null; 
       logBox.append("Bitmap generation complete\n"); 

decodeByteArray() Code:

public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts) { 
    if ((offset | length) < 0 || data.length < offset + length) { 
     throw new ArrayIndexOutOfBoundsException(); 
    } 

    Bitmap bm; 

    Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap"); 
    try { 
     bm = nativeDecodeByteArray(data, offset, length, opts); 

     if (bm == null && opts != null && opts.inBitmap != null) { 
      throw new IllegalArgumentException("Problem decoding into existing bitmap"); 
     } 
     setDensityFromOptions(bm, opts); 
    } finally { 
     Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS); 
    } 

    return bm; 
} 

Ich würde davon ausgehen, dass es nativeDecodeByteArray() ist, die fehlschlägt.

Ich bemerke auch die Log-Nachricht:

D/skia: --- SkImageDecoder :: Fabrik null zurück

Wer irgendwelche Ideen hat?

+0

'Aus den Daten muss ich eine Bitmap erzeugen.'. Welche Art von Daten erhalten Sie? Wenn Sie Bilddateien wie .png oder .jpg erhalten, ist Ihre Herangehensweise falsch. – greenapps

+0

Der Grabbing-Algorithmus ist relativ komplex, aber im Wesentlichen, was ich erhalte, sind RGB-Daten für Pixel in Form von 3 Bytes - aber die Reihenfolge, in der die Daten kommen, ist aufgrund der Hardware-Implementierung keine aufeinanderfolgenden Pixel –

Antwort

1

decodeByteArray von BitmapFactory tatsächlich dekodiert ein Bild, das heißt ein Bild, das in einem Format wie JPEG oder PNG codiert wurde. decodeFile und decodeStream machen ein wenig mehr Sinn, da Ihr codiertes Bild wahrscheinlich von einer Datei oder einem Server oder etwas kommen würde.

Sie wollen nichts entschlüsseln. Sie versuchen, rohe Bilddaten in eine Bitmap zu bekommen. Wenn Sie Ihren Code betrachten, wird eine 225 x 160-Bitmap mit 4 Byte pro Pixel im ARGB-Format erstellt. Also sollte dieser Code für Sie arbeiten:

int width = 225; 
    int height = 160; 
    int size = width * height; 
    int[] pixelData = new byte[size]; 
    for (int i = 0; i < size; i++) { 
     // pack 4 bytes into int for ARGB_8888 
     pixelData[i] = ((0xFF & (byte)255) << 24) // alpha, 8 bits 
       | ((0xFF & (byte)255) << 16)  // red, 8 bits 
       | ((0xFF & (byte)0) << 8)   // green, 8 bits 
       | (0xFF & (byte)0);    // blue, 8 bits 
    } 

    Bitmap image = Bitmap.createBitmap(pixelData, width, height, Bitmap.Config.ARGB_8888); 
+0

Das funktioniert perfekt, danke! –