zoukankan      html  css  js  c++  java
  • 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


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



  • 相关阅读:
    五、异步任务编排CompletableFuture
    四、fork/join框架
    三、阻塞等待异步结果FutureTask
    二、synchronized同步锁
    一、Java多线程基础
    6. ZigZag Conversion (字符串的连接)
    5. Longest Palindromic Substring (DP)
    4. Median of Two Sorted Arrays (二分法;递归的结束条件)
    3. Longest Substring Without Repeating Characters (ASCII码128个,建立哈西表)
    2. Add Two Numbers
  • 原文地址:https://www.cnblogs.com/riasky/p/3473271.html
Copyright © 2011-2022 走看看