Question

Dans le processus de suivi de graves problèmes de mémoire dans mon application, j'ai examiné plusieurs vidages de tas de mon application et la plupart du temps, j'ai un ÉNORME bitmap dont je ne connais pas l'existence.

Cela prend 9,4 Mo, soit 9 830 400 octets, ou en réalité une image de 1 280 x 1 920 à 4 octets par pixel.

J'ai vérifié dans Eclipse MAT, c'est bien un octet[9830400], qui a une référence entrante qui est un android.graphics.Bitmap.

J'aimerais transférer ceci dans un fichier et essayer de le voir.Je n'arrive pas à comprendre d'où ça vient.Ma plus grande image dans tous mes dessins est un png 640x960, qui prend moins de 3 Mo.

J'ai essayé d'utiliser Eclipse pour "copier la valeur dans un fichier", mais je pense qu'il imprime simplement le tampon dans le fichier, et je ne connais aucun logiciel d'image capable de lire un flux d'octets et de l'afficher sous forme de 4 octets par pixel. image.

Une idée?

Voici ce que j'ai essayé :videz le tableau d'octets dans un fichier, transférez-le vers /sdcard/img et chargez une activité comme celle-ci :

@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");
    }
}

Je n'ai rien vu.

Savez-vous comment est codée l’image ?Disons qu'il est stocké dans byte[] buffer. buffer[0] est rouge, buffer[1] est vert, etc.?

Était-ce utile?

La solution 2

OK - Après quelques essais infructueux, j'ai enfin reçu quelque chose de ce tableau d'octet.J'ai écrit ce programme C simple pour convertir le réseau d'octets en un fichier bitmap Windows.Je dépose le code au cas où quelqu'un est intéressé.
J'ai compilé cela contre VisualC 6.0 et GCC 3.4.4, il devrait fonctionner sur tout système d'exploitation (testé sur Windows, Linux et 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);
}

Ainsi, en utilisant cet outil, j'ai pu reconnaître la photo utilisée pour générer ce bitmap 1280x1920.

Autres conseils

voir ici pour une réponse plus facile: MAT (Eclipse Memory Analyzer) - Comment afficher des bitmaps de la mémoire de mémoire

TL; DR - Installez Gimp et chargez l'image comme RVB Right Alpha

J'ai trouvé qu'à partir de la dernière version d'Android Studio (2.2.2 au moment de la rédaction), vous pouvez afficher directement le fichier bitmap :

  1. Ouvrez l'onglet « Moniteur Android » (en bas à gauche), puis l'onglet Mémoire.
  2. Appuyez sur le bouton « Dump Java Heap »

  3. Choisissez le nom de classe « Bitmap » pour l’instantané actuel, sélectionnez chaque instance de bitmap et affichez quelle image consomme exactement plus de mémoire que prévu.(écrans 4 et 5)

  4. Choisir la Bitmap nom du cours…

enter image description here

  1. Sélectionnez chaque instance de bitmap

enter image description here

et faites un clic droit dessus, sélectionnez View Bitmap

enter image description here

Il suffit de prendre l'entrée sur l'image et de la convertir en un objet bitmap à l'aide du flux de fichiers / Datastream.Ajoutez également des journaux pour voir des données pour chaque image utilisée.

Vous pouvez activer une connexion USB et copier le fichier à un autre ordinateur avec plus d'outils pour rechercher.

Certains périphériques pourraient être configurés pour vider l'écran actuel sur le système de fichiers lorsque le bouton Démarrer est enfoncé.Peut-être que cela vous arrive.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top