Cocos2d-x使用android拍照功能加载照片内存过大,通过另存照片尺寸大小解决

使用2dx调用android拍照功能,拍照结束后在2dx界面显示拍照照片,如果不对照片做处理,会出现内存过大的问题,导致程序崩溃,如果仅仅另存拍照照片,则照片质量大小均下降,导致照片不够清晰,后来发现只需要修改照片尺寸大小就可以解决,而且质量没有太多改变,照片清晰足够。

调用拍照功能

	public static void onClickTakePhoto() {

		String state = Environment.getExternalStorageState();
		if (state.equals(Environment.MEDIA_MOUNTED)) {
			Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
			main.startActivityForResult(intent, PHOTO_GRAPH);
		} else {
			Toast.makeText(main, "摄像头不存在", Toast.LENGTH_SHORT).show();
		}
	}

拍照之后回调函数

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// Uri uri = data.getData();
		// Bitmap photo = null;
		// if (uri != null) {
		// photo = BitmapFactory.decodeFile(uri.getPath());
		// }
		// if (photo == null) {
		// Bundle bundle = data.getExtras();
		// if (bundle != null) {
		// photo = (Bitmap) bundle.get("data");
		// } else {
		// return;
		// }
		// }
		// try {
		// SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
		// Date curDate = new Date(System.currentTimeMillis());// 获取当前时间
		// String str = formatter.format(curDate);
		// System.out.println("++++++++++++" + str);// &&str=="08:00"
		// saveMyBitmap(photo, str);
		// } catch (IOException e) {
		// e.printStackTrace();
		// }

		if (requestCode == PHOTO_GRAPH) {// photo take
			if (data != null) {// 防止用户直接后退
				String imgpath = null;

				Bundle bundle = data.getExtras();
				Bitmap bitmap = (Bitmap) bundle.get("data");// 获取相机返回的数据,并转换为Bitmap图片格式

				Uri uri = data.getData();
				if (uri == null)
					uri = Uri.parse(MediaStore.Images.Media.insertImage(
							getContentResolver(), bitmap, null, null));
				// 方法1
				Cursor cursor = this.getContentResolver().query(uri, null,
						null, null, null);
				cursor.moveToFirst();
				imgpath = cursor.getString(cursor.getColumnIndex("_data"));// 获取绝对路径
				cursor.close();

				try {
					SimpleDateFormat formatter = new SimpleDateFormat(
							"yyyyMMddHHmmss");
					Date curDate = new Date(System.currentTimeMillis());// 获取当前时间
					String str = formatter.format(curDate);
					System.out.println("++++++++++++" + str);// &&str=="08:00"
					saveMyBitmap(bitmap, str, imgpath);//另存照片
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		super.onActivityResult(requestCode, resultCode, data);
	}

saveMyBitmap 可以根据获得的bitmap另存照片,也可以根据获得的照片路径另存照片,

我这里用的是路径另存照片,用bitmap另存照片之后发现照片质量下降,尽管不进行压缩也有这个问题

	// 保存照片
	public static int saveMyBitmap(Bitmap bitmap, String bitName, String imgpath)
			throws IOException {
		String PhotoPath = null;
		if (Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {
			// 得到sdCard文件对象
			File sdDir = Environment.getExternalStorageDirectory();
			// 得到sdCard的路径
			String path = sdDir.getAbsolutePath() + "/bxJiang/temp";
			File path1 = new File(path);
			if (!path1.exists()) {// 若不存在,创建目录,可以在应用启动的时候创建
				path1.mkdirs();
				System.out.println("sd file path create:" + path);
			}
			PhotoPath = path + "/" + bitName + ".jpg";// "/mnt/sdcard/bxJiang/head_tmp.jpg"
			System.out.println(PhotoPath);

			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			Bitmap bitmap2 = getimage(imgpath);//根据照片路径修改另存照片尺寸大小,质量改变很小
			bitmap2.compress(Bitmap.CompressFormat.JPEG, 100, baos);
			byte[] b = baos.toByteArray();
			System.out.println(b.length / 1024);
			BufferedOutputStream bos = null;
			try {
				bos = new BufferedOutputStream(new FileOutputStream(new File(
						PhotoPath)));
				bos.write(b, 0, b.length);
				bos.close();
				System.out.println("图片创建成功");
			} catch (Exception e) {
				e.printStackTrace();
			}
			// ========================
			// File f = new File(PhotoPath);
			// f.createNewFile();
			// FileOutputStream fOut = null;
			// try {
			// fOut = new FileOutputStream(f);
			// } catch (FileNotFoundException e) {
			// e.printStackTrace();
			// return 0;
			// }
			// bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
			// try {
			// fOut.flush();
			// } catch (IOException e) {
			// e.printStackTrace();
			// return 0;
			// }
			// try {
			// fOut.close();
			// } catch (IOException e) {
			// e.printStackTrace();
			// return 0;
			// }
		} else {
			System.out.println("no sd card");
			return 0;
		}
		// 发送文件路径到c++
		SendPhotoPathToC(PhotoPath, PhotoPath);// imgpath);
		return 1;
	}
	
	//根据照片路径修改另存照片尺寸大小,质量改变很小
	private static Bitmap getimage(String srcPath) {
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		// 开始读入图片,此时把options.inJustDecodeBounds 设回true了
		newOpts.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空

		newOpts.inJustDecodeBounds = false;
		int w = newOpts.outWidth;
		int h = newOpts.outHeight;
		System.out.println(w);
		System.out.println(h);
		// 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
		int ww = m_Wight;// 这里设置宽度为480f
		int hh = m_Height;// 这里设置高度为800f
		System.out.println(ww);
		System.out.println(hh);
		// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
		int be = 1;// be=1表示不缩放
		if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
			be = (int) (w / ww);
		} else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
			be = (int) (h / hh);
		}
		if (be <= 0)
			be = 1;
		System.out.println(be);
		newOpts.inSampleSize = be;// 设置缩放比例,照片高度和宽度都为原来的be分之一,即照片为原来的2*be分之一
		// 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
		return BitmapFactory.decodeFile(srcPath, newOpts);
	}

	
	//根据bitmap修改另存照片尺寸大小,没有调用,存在一些问题
	private static Bitmap comp(Bitmap image) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		// 开始读入图片,此时把options.inJustDecodeBounds 设回true了
		newOpts.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
		newOpts.inJustDecodeBounds = false;
		int w = newOpts.outWidth;
		int h = newOpts.outHeight;
		System.out.println(w);
		System.out.println(h);
		float hh = m_Height;// 这里设置高度为800f
		float ww = m_Wight;// 这里设置宽度为480f
		// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
		int be = 1;// be=1表示不缩放
		if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
			be = (int) (w / ww);
		} else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
			be = (int) (h / hh);
		}
		if (be <= 0)
			be = 1;
		newOpts.inSampleSize = be;// 设置缩放比例
		return BitmapFactory.decodeStream(isBm, null, newOpts);
	}


下面贴一下我的手机获得的参数

w = 1552 , h = 2592   //拍照照片的尺寸,大小为758KB

ww = 480 , hh = 800    //手机分辨率

be = 3

最终照片参数

776*1296  742KB


有个问题不太明白,为什么照片大小一样的情况下,尺寸过大的照片加载显示会内存过大挂掉,而尺寸小的却不会?



原文地址:https://www.cnblogs.com/riasky/p/3473271.html