现在的位置: 首页 > 综合 > 正文

从Eclipse Memory Analyzer中获取内存中未释放的bitmap到bmp图片

2016年10月16日 ⁄ 综合 ⁄ 共 4939字 ⁄ 字号 评论关闭

Eclipse Memory Analyzer并不提供从一个bitmap buffer直接观察图片内容的功能,下面的步骤教你从bitmap buffer中导出一个我们能够直接浏览的图片:

1. 存储要浏览的bitmap buffer

domtree

2. 将bitmap buffer存到本地电脑中

输入或选择要存放图片的本地路径
savebuffer

3. 在Eclipse中打开inspector视图

当你要将存好的bitmap buffer转换成普通图片时,需要知道bitmap所对应图片的宽高,从inspector视图中可以得到。

inspectorview

showview

4. 从inspector视图中找到bitmap的宽高

imagedim

5. 将bitmap buffer文件转换为bmp图片文件

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;

public class MATBitmap {
	/* Constants */
	public static final int RMASK = 0x00ff0000;
	public static final int GMASK = 0x0000ff00;
	public static final int BMASK = 0x000000ff;
	public static final int AMASK = 0xff000000;
	private static final int SIZE_OF_HEADER = 12;
	private static final int SIZE_OF_DIB_HEADER = 108;
	private static final int SIZE_OF_MAGIC = 2;

	/* Structures */
	class bmpfile_magic {
		byte magic[];
	};

	static class BMPFile_header {
		int filesz;
		short creator1;
		short creator2;
		int bmp_offset;

		public byte[] getBytes() {
			try {
				ByteBuffer out = ByteBuffer.allocate(SIZE_OF_HEADER); 
				out.order(ByteOrder.LITTLE_ENDIAN);   				
//				ByteArrayOutputStream bout = new ByteArrayOutputStream();
//				DataOutputStream out = new DataOutputStream(bout);
				out.putInt(filesz);
				out.putShort(creator1);
				out.putShort(creator2);
				out.putInt(bmp_offset);
				return out.array();
			} catch (Exception e) {

			}
			return null;
		}
	};

	static class BMPFile_dibheader {
		int header_sz;
		int width;
		int height;
		short nplanes;
		short bitspp;
		int compress_type;
		int bmp_bytesz;
		int hres;
		int vres;
		int ncolors;
		int nimpcolors;

		int rmask, gmask, bmask, amask;
		int colorspace_type;
		byte[] colorspace = new byte[0x24];
		int rgamma, ggamma, bgamma;

		public byte[] getBytes() {
			try {
				ByteBuffer out = ByteBuffer.allocate(SIZE_OF_DIB_HEADER); 
				out.order(ByteOrder.LITTLE_ENDIAN);   				
				out.putInt(header_sz);
				out.putInt(width);
				out.putInt(height);
				out.putShort(nplanes);
				out.putShort(bitspp);
				out.putInt(compress_type);
				out.putInt(bmp_bytesz);
				out.putInt(hres);
				out.putInt(vres);
				out.putInt(ncolors);
				out.putInt(nimpcolors);
				
				out.putInt(rmask);
				out.putInt(gmask);
				out.putInt(bmask);
				out.putInt(amask);
				out.putInt(colorspace_type);

				out.put(colorspace);
				
				out.putInt(rgamma);
				out.putInt(ggamma);
				out.putInt(bgamma);
				return out.array();
				
			} catch(Exception e) {
				e.printStackTrace();
			}
			return null;
		}
	};

	/* Displays usage info and exits */
	private static void usage() {
		System.out
				.println("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");
		System.exit(0);
	}

	/* C entry point */
	public static void main(String[] args) {
//		args = new String[4];
//		args[0] = "c:/0x100.png";
//		args[1] = "c:/conv1.bmp";
//		args[2] = "512";
//		args[3] = "512";
		try {
			FileInputStream in;
			FileOutputStream out;
			String file_in, file_out;
			int w, h, W, H;
			byte r, g, b, a, image[];
			byte[] magic = new byte[2];
			BMPFile_header header = new BMPFile_header();
			BMPFile_dibheader dibheader = new BMPFile_dibheader();

			/* Parse command line */
			if (args.length != 4) {
				usage();
			}
			file_in = args[0];
			file_out = args[1];
			W = Integer.parseInt(args[2]);
			H = Integer.parseInt(args[3]);

			in = new FileInputStream(file_in);
			out = new FileOutputStream(file_out);

			/* Check parameters */
			if (in == null || out == null || W == 0 || H == 0) {
				usage();
			}

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

			header.filesz = W * H * 4 + magic.length + SIZE_OF_HEADER
					+ SIZE_OF_DIB_HEADER;
			header.creator1 = 0;
			header.creator2 = 0;
			header.bmp_offset = SIZE_OF_MAGIC + SIZE_OF_HEADER
					+ SIZE_OF_DIB_HEADER;

			dibheader.header_sz = SIZE_OF_DIB_HEADER;
			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;
			Arrays.fill(dibheader.colorspace, (byte)0);
			dibheader.rgamma = dibheader.bgamma = dibheader.ggamma = 0;

			/* Read picture data */
			image = new byte[4 * W * H];
			if (image == null) {
				System.out.println("Could not allocate a %d-byte buffer. : "
						+ (4 * W * H));
				System.exit(0);
			}
			in.read(image);
			in.close();

			/* Write header */
			out.write(magic);
			out.write(header.getBytes());
			out.write(dibheader.getBytes());
			System.out.println("Started writing");
			/* Convert the byte array to BMP format */
			ByteArrayOutputStream bout = new ByteArrayOutputStream();
			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];

					bout.write(b);
					bout.write(g);
					bout.write(r);
					bout.write(a);
				}
			}
			out.write(bout.toByteArray());
			bout.close();
			System.out.println("Finishe writing");
			image = null;
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

将上面java代码存为MATBitmap.java,然后将该java文件与本地存储的buffer文件存到同一目录下,随后在该目录中调起命令行采用下列格式执行命令:

1 Java MATBitmap.java <input.bmp> <output.bmp> <bitmap width> <bitmap height>

Example

1 java MATBitmap debug.bmp converted.bmp 800 800

然后就可以用普通图片浏览器观察定位该bitmap文件了,从而可以定位内存中未释放的资源

抱歉!评论已关闭.