Pregunta

En el proceso de seguimiento de los graves problemas de memoria en mi app, he mirado varias montón volcados desde mi aplicación, y la mayoría del tiempo tengo un GRAN mapa de bits que no conozco.

Toma 9.4 MB, o 9,830,400 bytes, o en realidad un 1280x1920 imagen en 4 bytes por píxeles.

Me registré en Eclipse MAT, de hecho es un byte[9830400], que tiene un entrante de referencia que es un android.graphics.Bitmap.

Me gustaría volcar esto en un archivo e intente ver las cosas.Yo no puedo entender de dónde está viniendo.Mi imagen más grande en toda mi dibujables es un 640x960 png, que lleva menos de 3 MB.

Traté de usar Eclipse para "copiar valor a" archivo", pero creo que simplemente imprime el búfer para el archivo, y yo no conozco a ninguna imagen de software que puede leer una secuencia de bytes y mostrarlo como un 4 bytes por píxel de la imagen.

Alguna idea?

Aquí es lo que he intentado:volcado de la matriz de bytes en un archivo, pulse a /sdcard/img, y la carga de una actividad como esta:

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    try {
        final File inputFile = new File("/sdcard/img");
        final FileInputStream isr = new FileInputStream(inputFile);
        final Bitmap bmp = BitmapFactory.decodeStream(isr);
        ImageView iv = new ImageView(this);
        iv.setImageBitmap(bmp);
        setContentView(iv);
        Log.d("ImageTest", "Image was inflated");
    } catch (final FileNotFoundException e) {
        Log.d("ImageTest", "Image was not inflated");
    }
}

Yo no veo nada.

¿Sabe usted cómo se codifica la imagen?Dicen que es almacenado en la byte[] buffer. buffer[0] es de color rojo, buffer[1] es de color verde, etc?

¿Fue útil?

Solución 2

BIEN, Después de algunos intentos fallidos, por fin tengo algo de esta matriz de bytes.Escribí este sencillo programa en C para convertir la matriz de bytes en un archivo de mapa de bits de Windows.Me estoy cayendo el código en caso de que alguien esté interesado.
He compilado esta en contra de VisualC 6.0 y gcc 3.4.4, que debería funcionar en cualquier sistema operativo (probado en Windows, Linux y MacOS X).

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>

/* Types */
typedef unsigned char byte;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef int int32_t;

/* Constants */
#define RMASK 0x00ff0000
#define GMASK 0x0000ff00
#define BMASK 0x000000ff
#define AMASK 0xff000000

/* Structures */
struct bmpfile_magic {
  unsigned char magic[2];
};

struct bmpfile_header {
  uint32_t filesz;
  uint16_t creator1;
  uint16_t creator2;
  uint32_t bmp_offset;
};

struct bmpfile_dibheader {
  uint32_t header_sz;
  uint32_t width;
  uint32_t height;
  uint16_t nplanes;
  uint16_t bitspp;
  uint32_t compress_type;
  uint32_t bmp_bytesz;
  int32_t hres;
  int32_t vres;
  uint32_t ncolors;
  uint32_t nimpcolors;

  uint32_t rmask, gmask, bmask, amask;
  uint32_t colorspace_type;
  byte colorspace[0x24];
  uint32_t rgamma, ggamma, bgamma;
};

/* Displays usage info and exits */
void usage(char *cmd) {
    printf("Usage:\t%s <img_src> <img_dest.bmp> <width> <height>\n"
        "\timg_src:\timage byte buffer obtained from Eclipse MAT, using 'copy > save value to file' while selecting the byte[] buffer corresponding to an android.graphics.Bitmap\n"
        "\timg_dest:\tpath to target *.bmp file\n"
        "\twidth:\t\tpicture width, obtained in Eclipse MAT, selecting the android.graphics.Bitmap object and seeing the object member values\n"
        "\theight:\t\tpicture height\n\n", cmd);
    exit(1);
}

/* C entry point */
int main(int argc, char **argv) {
    FILE *in, *out;
    char *file_in, *file_out;
    int w, h, W, H;
    byte r, g, b, a, *image;
    struct bmpfile_magic magic;
    struct bmpfile_header header;
    struct bmpfile_dibheader dibheader;

    /* Parse command line */
    if (argc < 5) {
        usage(argv[0]);
    }
    file_in = argv[1];
    file_out = argv[2];
    W = atoi(argv[3]);
    H = atoi(argv[4]);
    in = fopen(file_in, "rb");
    out = fopen(file_out, "wb");

    /* Check parameters */
    if (in == NULL || out == NULL || W == 0 || H == 0) {
        usage(argv[0]);
    }

    /* Init BMP headers */
    magic.magic[0] = 'B';
    magic.magic[1] = 'M';

    header.filesz = W * H * 4 + sizeof(magic) + sizeof(header) + sizeof(dibheader);
    header.creator1 = 0;
    header.creator2 = 0;
    header.bmp_offset = sizeof(magic) + sizeof(header) + sizeof(dibheader);

    dibheader.header_sz = sizeof(dibheader);
    dibheader.width = W;
    dibheader.height = H;
    dibheader.nplanes = 1;
    dibheader.bitspp = 32;
    dibheader.compress_type = 3;
    dibheader.bmp_bytesz = W * H * 4;
    dibheader.hres = 2835;
    dibheader.vres = 2835;
    dibheader.ncolors = 0;
    dibheader.nimpcolors = 0;
    dibheader.rmask = RMASK;
    dibheader.gmask = BMASK;
    dibheader.bmask = GMASK;
    dibheader.amask = AMASK;
    dibheader.colorspace_type = 0x57696e20;
    memset(&dibheader.colorspace, 0, sizeof(dibheader.colorspace));
    dibheader.rgamma = dibheader.bgamma = dibheader.ggamma = 0;

    /* Read picture data */
    image = (byte*) malloc(4*W*H);
    if (image == NULL) {
        printf("Could not allocate a %d-byte buffer.\n", 4*W*H);
        exit(1);
    }
    fread(image, 4*W*H, sizeof(byte), in);
    fclose(in);

    /* Write header */
    fwrite(&magic, sizeof(magic), 1, out);
    fwrite(&header, sizeof(header), 1, out);
    fwrite(&dibheader, sizeof(dibheader), 1, out);

    /* Convert the byte array to BMP format */
    for (h = H-1; h >= 0; h--) {
        for (w = 0; w < W; w++) {
            r = *(image + w*4 + 4 * W * h);
            b = *(image + w*4 + 4 * W * h + 1);
            g = *(image + w*4 + 4 * W * h + 2);
            a = *(image + w*4 + 4 * W * h + 3);

            fwrite(&b, 1, 1, out);
            fwrite(&g, 1, 1, out);
            fwrite(&r, 1, 1, out);
            fwrite(&a, 1, 1, out);
        }
    }

    free(image);
    fclose(out);
}

Así que el uso de esta herramienta, pude reconocer la imagen utilizada para generar este 1280x1920 de mapa de bits.

Otros consejos

Ver aquí para una respuesta más sencilla: MAT (Eclipse de la Memoria del Analizador) - cómo ver los mapas de bits de volcado de memoria

TL;DR - Instalar GIMP y cargar la imagen en formato raw RGB Alfa

He encontrado que a partir de la última versión de Android Studio (2.2.2 como de la escritura), usted puede ver el archivo de mapa de bits directamente:

  1. Abrir el Android de Monitor' ficha (en la parte inferior izquierda) y luego a la pestaña Memoria.
  2. Pulse la tecla de "Volcado de Java Heap' botón

  3. Elija el " mapa de bits de la Clase Nombre de la instantánea actual, seleccione cada Instancia de mapa de bits y ver qué imagen exactamente consumen más memoria de la que se esperaba.(pantallas de 4 y 5)

  4. Elija el Bitmap nombre de la clase...

enter image description here

  1. Seleccione cada Instancia de mapa de bits

enter image description here

y haga clic en él, seleccione View Bitmap

enter image description here

Acaba de tomar la información de entrada para la imagen y la convierte en un objeto de mapa de bits mediante el uso de la fileinput corriente/flujo de datos.También agregar registros para ver los datos de cada imagen que se utiliza.

Podría habilitar una conexión usb y copiar el archivo a otro equipo con más herramientas para investigar.

Algunos dispositivos podrían ser configurado para el volcado de la pantalla actual del sistema de archivos cuando se pulsa el botón start.Tal vez esto le sucede a usted.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top