How to actually see a bitmap taken from an Android heap dump

While tracking serious memory issues in my application, I looked at a few heap heaps from my application, and most of the time I have a HUGE bitmap that I donโ€™t know about.

It requires 9.4MB, or 9,830,400 bytes, or actually a 1280x1920 image with 4 bytes per pixel.

I checked in Mcl Eclipse, this is really a byte [9830400], which has one inbound link, which is android.graphics.Bitmap .

I want to dump this to a file and try to see it. I canโ€™t understand where he is from. My largest image in all of my drawings is 640x960 png, which takes up less than 3 MB.

I tried using Eclipse to "copy the value to a file", but I think it just prints a buffer to a file, and I don't know any image software that can read a stream of bytes and display it as 4 bytes per pixel.

Any idea?

Here is what I tried: uploaded an array of bytes to a file, click it on / sdcard / img and load this activity:

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

I have not seen anything.

Do you know how the image is encoded? Let's say it is stored in byte[] buffer . buffer[0] red, buffer[1] green, etc.

+6
source share
5 answers

OK. After a rather unsuccessful attempt, I finally got something from this byte array. I wrote this simple program to convert a byte array to a Windows Bitmap file. I discard the code in case anyone is interested.
I compiled this against VisualC 6.0 and gcc 3.4.4, it should work on any OS (tested on Windows, Linux and 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); } 

Thus, using this tool, I was able to recognize the image used to create the 1280x1920 bitmap.

+2
source

See here for an easier answer: MAT (Eclipse Memory Analyzer) - how to view bitmaps from a memory dump

TL DR - install GIMP and upload the image as raw alpha alpha

+4
source

Just take image input and convert it to a bitmap object using the fileinput / datastream stream. Also add logs to view data for each image used.

0
source

You can enable the USB connection and copy the file to another computer with a lot of research tools.

Some devices may be configured to reset the current screen to the file system by pressing the start button. Perhaps this is happening to you.

0
source

I found that starting from the latest version of Android Studio (2.2.2 from the moment of writing), you can directly view the bitmap file:

  • Click the Android Monitor tab (bottom left), and then the Memory tab.
  • Click the Java Heap Dump button

  • Select the โ€œBitmap class name for the current snapshot, select each instance of the bitmap, and see which image accurately consumes more memory than expected. (Screens 4 and 5)

  • Select a Bitmap Class Name ...

enter image description here

  1. Select each bitmap instance.

enter image description here

and right click on it, select View Bitmap

enter image description here

0
source

Source: https://habr.com/ru/post/910219/


All Articles