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


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



 

你可能感兴趣的:(cocos2d-x)