Android调用相机拍照,压缩图片后保存SD卡中
2016-06-23 14:19
465 查看
最近在搞一个项目,需求是调用系统相机拍完照片后保存本地,再上传至后台服务器,但为了节省流量需要压缩上传,将图片压缩至100K以内。这个是在特定机器上运行,类似于手持POS机,但是它的相机几乎没有优化,对焦慢,而且拍照也不清晰,使用自己的手机调用系统相机拍照后图片大概有300K左右,自动已经压缩了,但这个机器没有优化,调用相机拍照后的图片和原图一样2M左右,太大了,必须要压缩!
网上找了些资料,也作为参考:Android图片压缩 质量压缩和尺寸压缩;安卓相机拍摄照片,压缩后存储于SD卡
项目需要的效果为:
上代码:
页面布局很简单,就两个Button跟一个ImageView,这里就不贴代码了。
效果图片:
SD卡中的图片:
可以看到,file2.jpg是压缩过的,file1.jpg是原图,因为是模拟器,效果不太明显,在真机上压缩后的图片在100K之内。
要调用相机和读写SD卡,最后不要忘了加权限。
代码下载
因为工作的原因,这里使用的是Myeclipse不过Eclipse也可以用。
网上找了些资料,也作为参考:Android图片压缩 质量压缩和尺寸压缩;安卓相机拍摄照片,压缩后存储于SD卡
项目需要的效果为:
上代码:
import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener{ private Button openCamera,openCamera2; private ImageView showImgView; Uri photoUri; String filePath; //图片路径 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findView(); } private void findView() { // TODO Auto-generated method stub openCamera = (Button) findViewById(R.id.openCamera); openCamera2 = (Button) findViewById(R.id.openCamera2); showImgView = (ImageView) findViewById(R.id.showImgView); openCamera.setOnClickListener(this); openCamera2.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()){ case R.id.openCamera: //打卡相机前先检测SD卡是否可以用 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ photoUri = patrUri("file1"); startCamera(1001,photoUri); }else{ Toast.makeText(MainActivity.this, "SD卡不可用", Toast.LENGTH_SHORT).show(); } break; case R.id.openCamera2: if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ photoUri = patrUri("file2"); startCamera(1002,photoUri); }else{ Toast.makeText(MainActivity.this, "SD卡不可用", Toast.LENGTH_SHORT).show(); } break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); if(requestCode == 1001){ if(resultCode == RESULT_OK){ FileInputStream is = null; try { is = new FileInputStream(filePath); Bitmap bitmap = BitmapFactory.decodeStream(is); showImgView.setImageBitmap(bitmap); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { is.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } if(requestCode == 1002){ if(resultCode == RESULT_OK){ try { Bitmap bitmap = compressBySize(filePath,480,800); //设置压缩后图片的高度和宽度 saveFile(bitmap,filePath); showImgView.setImageBitmap(bitmap); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } // 压缩图片尺寸 private static Bitmap compressBySize(String pathName, int targetWidth, int targetHeight) { BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inJustDecodeBounds = true;// 不去真的解析图片,只是获取图片的头部信息,包含宽高等; Bitmap bitmap = BitmapFactory.decodeFile(pathName, opts); // 得到图片的宽度、高度; float imgWidth = opts.outWidth; float imgHeight = opts.outHeight; // 分别计算图片宽度、高度与目标宽度、高度的比例;取大于等于该比例的最小整数; int widthRatio = (int) Math.ceil(imgWidth / (float) targetWidth); int heightRatio = (int) Math.ceil(imgHeight / (float) targetHeight); opts.inSampleSize = 1; if (widthRatio > 1 || widthRatio > 1) { if (widthRatio > heightRatio) { opts.inSampleSize = widthRatio; } else { opts.inSampleSize = heightRatio; } } // 设置好缩放比例后,加载图片进内容; opts.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeFile(pathName, opts); return bitmap; } //保存压缩后的图片 private void saveFile(Bitmap bitmap, String filePath2) throws IOException { // TODO Auto-generated method stub File testFile = new File(filePath2); if (testFile.exists()) { testFile.delete(); } File myCaptureFile = new File(filePath2); System.out.println("------filePath2==" + filePath2); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(myCaptureFile)); // 100表示不进行压缩,70表示压缩率为30% bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bos); bos.flush(); bos.close(); } //打开相机 private void startCamera(int requestCode, Uri photoUri) { // TODO Auto-generated method stub Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT,photoUri); startActivityForResult(intent, requestCode); } /** * 图片保存路径 这里是在SD卡目录下创建了MyPhoto文件夹 * @param fileName * @return */ private Uri patrUri(String fileName) { //指定了图片的名字,可以使用时间来命名 // TODO Auto-generated method stub String strPhotoName = fileName+".jpg"; String savePath = Environment.getExternalStorageDirectory().getPath() + "/MyPhoto/"; File dir = new File(savePath); if (!dir.exists()) { dir.mkdirs(); } filePath = savePath + strPhotoName; return Uri.fromFile(new File(dir, strPhotoName)); } }
页面布局很简单,就两个Button跟一个ImageView,这里就不贴代码了。
效果图片:
SD卡中的图片:
可以看到,file2.jpg是压缩过的,file1.jpg是原图,因为是模拟器,效果不太明显,在真机上压缩后的图片在100K之内。
要调用相机和读写SD卡,最后不要忘了加权限。
代码下载
因为工作的原因,这里使用的是Myeclipse不过Eclipse也可以用。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories