前段时间写过一片关于照片上传的文章,但是后来发现用那种方式上传的图片是经过android系统处理过的,并不是原图,也就是说经过压缩过的,图片会变得很小,今天我就是为了解决这个问题用另外一种方式实现。
首先当我们要得到原有的照片必须为拍照后的照片指定存放的路径地址,这个地址是在Intent中指定,方法是intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
其中file就是手机本地的对应的输出文件,这个需要在传入参数前就生成,不然会报FileNotFoundException,下面是源码:
destoryBimap(); String state = Environment.getExternalStorageState(); if (state.equals(Environment.MEDIA_MOUNTED)) { String saveDir = Environment.getExternalStorageDirectory() + "/temple"; File dir = new File(saveDir); if (!dir.exists()) { dir.mkdir(); } file = new File(saveDir, "temp.jpg"); file.delete(); if (!file.exists()) { try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(ReportSurveyPointActivity.this, R.string.photo_file_isnull, Toast.LENGTH_LONG).show(); return; } } Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); startActivityForResult(intent, REQUEST_CODE); } else { Toast.makeText(ReportSurveyPointActivity.this, R.string.common_msg_nosdcard, Toast.LENGTH_LONG) .show(); }
其中destoryBimap()这个方法已经在上一篇文章中介绍过了,是为了把照片从手机内存中清楚调,不然黑容易报内存溢出异常,毕竟原图片比较大。下面就是判断手机是否装载SDCard,接下来在SDCard上生成我们照片保存的地址。
那么接下来就是在onActivityResult()方法中加载我们的照片,这下加载照片就非常简单了,因为在拍照前我们已经给除了照片的路径,我们根据这个路径把照片加载进来就行了,下面是源码:
protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE) { if (resultCode != RESULT_OK) { return; } if (file != null && file.exists()) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; photo = BitmapFactory.decodeFile(file.getPath(), options); photo_image.setBackgroundDrawable(new BitmapDrawable(photo)); pictureDir = file.getPath(); } else { Toast.makeText(this, R.string.photo_file_isnull, Toast.LENGTH_LONG).show(); } } }
这里需要说明一下的就是,当我们要在程序预览照片的时候由于照片比较大,考虑到内存问题,所以我们要把照片进行压缩再放到控件里面,压缩照片的方法就是用BitmapFactory.Options类的inSampleSize这个属性,这个属性的意思说在原照片的大小的多少比例来展示相片,也就是个百分比。我这里是设置的2,也就是说原照片的一般的大小展示。
下面是销毁照片的方法:
/** * 销毁图片文件 */ private void destoryBimap() { if (photo != null && !photo.isRecycled()) { photo.recycle(); photo = null; } }
这个方法我是在每次拍照前和onDestroy()方法中都调用了的,都是处于内存考虑,如果你是dialog的话还建议在dimisslistener中调。
至于大家经常问道的上传照片到后台的方法我也顺便说下,我是用的HttpClient实现的很简单,而后台就是随便什么框架都行,下面是上传照片的方法实现:
/** * 提交参数里有文件的数据 * * @param url * 服务器地址 * @param param * 参数 * @return 服务器返回结果 * @throws Exception */ public static String uploadSubmit(String url, Map<String, String> param, File file) throws Exception { HttpPost post = new HttpPost(url); MultipartEntity entity = new MultipartEntity(); if (param != null && !param.isEmpty()) { for (Map.Entry<String, String> entry : param.entrySet()) { if (entry.getValue() != null && entry.getValue().trim().length() > 0) { entity.addPart(entry.getKey(), new StringBody(entry.getValue())); } } } // 添加文件参数 if (file != null && file.exists()) { entity.addPart("file", new FileBody(file)); } post.setEntity(entity); HttpResponse response = httpClient.execute(post); int stateCode = response.getStatusLine().getStatusCode(); StringBuffer sb = new StringBuffer(); if (stateCode == HttpStatus.SC_OK) { HttpEntity result = response.getEntity(); if (result != null) { InputStream is = result.getContent(); BufferedReader br = new BufferedReader( new InputStreamReader(is)); String tempLine; while ((tempLine = br.readLine()) != null) { sb.append(tempLine); } } } post.abort(); return sb.toString(); }