android如何在拍照时候获取高清图片
程序员文章站
2024-03-22 19:52:04
...
首先来看段代码~
public class MainActivity extends AppCompatActivity {
/**
*
* genymontion有时候特别坑,摄像头都开不开。。
*
*/
@BindView(R.id.takephotoTV)
Button takephotoTV;
@BindView(R.id.imageIV)
ImageView imageIV;
private final int CAMERA_REQUEST = 8888;
@BindView(R.id.bt2)
//这个按钮是重新加载的按钮
Button bt2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
@OnClick(R.id.takephotoTV)
public void onClick() {
//下面这个语句就是开摄像头
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//开摄像头都是要开回调的
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
//if (requestCode == CAMERA_REQUEST){
Bitmap photo = (Bitmap) data.getExtras().get("data");
imageIV.setImageBitmap(photo);
bt2.setVisibility(View.VISIBLE);
}
}
}
如果把onActivityresult里面的data直接拿出来用的话,得到的图片一定是模糊的,不信可以直接copy上面代码到自己项目中(这里我用的butterknie来代替findviewbyid,不会用的同学直接换成findviewbyid即可)。至于为什么,目前我只是推测,应该是强转intent参数强转 bitmap,安卓自动为图片进行了压缩。
那么有木有拍照之后获取高清无码大图的方法呢?开始,我也很纠结啊,看了一篇大神博客(连接找不到了,大概是13年的~),得知如果想要获取高清图,首先就要在拍照的时候,指定一个拍照之后保存图片的位置,使用的核心方法是
Uri imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),"image.jpg"));
先说明一个有坑的地方,我试了很多次都是这样,就是这个保存的file地址必须是sk卡的路径,不然点击了摄像机之后,然后就无法返回了~(不信去试试)
好了下面是代码
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //调用系统相机
Uri imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "image.jpg"));
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, 100); //用户点击了从相机获取
然后Activityresult中的方法如下:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case 100:
Bitmap makephotobitmap = compressImage(new File(Environment.getExternalStorageDirectory(), "image.jpg").getPath());
saveImage( makephotobitmap, photoname1);
break;
}
}
}
然后里面compressImage是压缩方法,因为展示到界面上的图片大小太大了,不然会oom,可以用模拟器看看sd卡这个路径保存刚才拍照图片的大小你就知道了!!(如果不知道为啥要压缩图片的同学,自行百度安卓图片压缩,下面的压缩方法基本上使用与一切大图的压缩)
public Bitmap compressImage(String filepath) {
int height = getWindowManager().getDefaultDisplay().getHeight();
int width = getWindowManager().getDefaultDisplay().getWidth();
Point p = new Point();
getWindowManager().getDefaultDisplay().getSize(p);
width = p.x;
height = p.y;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
//下面这个是获取不到大小的,因为加载进内存的大小为0
Bitmap bitmap = BitmapFactory.decodeFile(filepath);
BitmapFactory.decodeFile(filepath, options);
//Log.e("--压缩之前", bitmap.getByteCount() + " ");
int outHeight = options.outHeight;
int outWidth = options.outWidth;
int index = 1;
if (outHeight > height || outWidth > width) {
float heightRate = outHeight / height;
float widthrate = outHeight / width;
index = (int) Math.max(heightRate, widthrate);
}
options.inSampleSize = index;
options.inJustDecodeBounds = false;
Bitmap afterbitmap = BitmapFactory.decodeFile(filepath, options);
//Log.e("--压缩之后", afterbitmap.getByteCount() + " ");
return afterbitmap;
}
//这里为啥要有保存图片的方法,这是把压缩之后的图片放在指定的文件夹
public static void saveImage( Bitmap bmp, String photoname) {
File appDir = new File(Environment.getExternalStorageDirectory(), "emiaoqian");
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = photoname;
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
//100%品质就是不会压缩,这里只是把图片保存到另一个地方
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
好啦,这样就大功告成啦~安卓模拟器的测试版本为5.0,然后需要的权限是
<uses-permission android:name="ANDROID.PERMISSION.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
如果你用6.0的模拟器则要用到动态权限,然后7.0的模拟器还有不能直接在代码中传递uri的问题。所以目前测试的模拟器的版本为5.0,超过5.0的很可能报错~~
推荐阅读