100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Android调用照相机拍照

Android调用照相机拍照

时间:2021-10-03 03:28:39

相关推荐

Android调用照相机拍照

之前写在别的网站上写博客。后来没有坚持下来,以至于账号密码都忘了,好啦说正事

Android调用照相机拍照 这个在现在的应用中很常见,首先如果拍照是应用的必要功能,那么应该令它在Google Play中仅对有相机的设备可见。为了让用户知道我们的应用需要依赖相机,在Manifest清单文件中添加<uses-feature>标签:

<manifest ... ><uses-feature android:name="android.hardware.camera"android:required="true" />...</manifest>

如果我们的应用使用相机,但相机并不是应用的正常运行所必不可少的组件,可以将android:required设置为"false"。这样的话,Google Play 也会允许没有相机的设备下载该应用。当然我们有必要在使用相机之前通过调用hasSystemFeature(PackageManager.FEATURE_CAMERA)方法来检查设备上是否有相机。如果没有,我们应该禁用和相机相关的功能!FEATURE_CAMERA_FRONT(检测是否含有前置摄像头)FEATURE_CAMERA(检测是否含有后置摄像头)FEATURE_CAMERA_ANY(检测是否含有任意一个摄像头)context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);

1.resolveActivity方法:

在自己的应用程序中利用第三方应用程序的Activity和Service是十分方便的,但是你无法保证用户设备上安装了特定的某个应用软件,或者设备上有能够处理你的Intent请求的程序。

因此,在启动第三方APK里的Activity之前,确定调用是否可以解析为一个Activity是一种很好的做法。

通过Intent的resolveActivity方法,并想该方法传入包管理器可以对包管理器进行查询以确定是否有Activity能够启动该Intent

static final int REQUEST_IMAGE_CAPTURE = 1;private void dispatchTakePictureIntent() {

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

if (takePictureIntent.resolveActivity(getPackageManager()) != null) {

startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);

}}

注意在调用startActivityForResult()方法之前,先调用resolveActivity(),这个方法会返回能处理该Intent的第一个Activity(译注:即检查有没有能处理这个Intent的Activity)。执行这个检查非常重要,因为如果在调用startActivityForResult()时,没有应用能处理你的Intent,应用将会崩溃。所以只要返回结果不为null,使用该Intent就是安全的。

Android的相机应用会把拍好的照片编码为缩小的Bitmap,使用extra value的方式添加到返回的Intent当中,并传送给onActivityResult(),对应的Key为"data"。下面的代码展示的是如何获取这一图片并显示在ImageView上。

<pre name="code" class="java">@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {Bundle extras = data.getExtras();Bitmap imageBitmap = (Bitmap) extras.get("data");mImageView.setImageBitmap(imageBitmap);}}

这张从"data"中取出的缩略图适用于作为图标,但其他作用会比较有限。而处理一张全尺寸图片需要做更多的工作。

2.拍摄并将图片存到SD卡内,然后显示在imageView中

public void click(View view) {Intent intent = new Intent();// 指定拍照的意图。intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); // 指定保存文件的路径startActivityForResult(intent, 100);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if(requestCode==100){

iv.setImageURI(Uri.fromFile(file));}super.onActivityResult(requestCode, resultCode, data);}

因为写权限隐含了读权限,所以如果需要外部存储的写权限,那么仅仅需要请求一项权限就可以了:

<manifest ...><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />...</manifest>

一旦选定了存储文件的目录,我们还需要设计一个保证文件名不会冲突的命名规则。当然我们还可以将路径存储在一个成员变量里以备在将来使用。下面的例子使用日期时间戳作为新照片的文件名:

String mCurrentPhotoPath;private File createImageFile() throws IOException {String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());String imageFileName = "JPEG_" + timeStamp + "_";File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); //图片保存的标准路径Environment.DIRECTORY_PICTURESFile image = File.createTempFile(imageFileName, ".jpg", storageDir); mCurrentPhotoPath = "file:" + image.getAbsolutePath();//获取绝对路径return image;}

有了上面的方法,我们就可以给新照片创建文件对象了,现在我们可以像这样创建并触发一个Intent:

static final int REQUEST_TAKE_PHOTO = 1;private void dispatchTakePictureIntent() {Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);if (takePictureIntent.resolveActivity(getPackageManager()) != null) {File photoFile = null;try {photoFile = createImageFile();} catch (IOException ex) {...}if (photoFile != null) {takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photoFile));startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);}}}

将照片添加到相册中

由于我们通过Intent创建了一张照片,因此图片的存储位置我们是知道的。对其他人来说,也许查看我们的照片最简单的方式是通过系统的Media Provider。

Note:如果将图片存储在getExternalFilesDir()提供的目录中,Media Scanner将无法访问到我们的文件,因为它们隶属于应用的私有数据。

下面的例子演示了如何触发系统的Media Scanner,将我们的照片添加到Media Provider的数据库中,这样就可以使得Android相册程序与其他程序能够读取到这些照片。

private void galleryAddPic() {Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);File f = new File(mCurrentPhotoPath);Uri contentUri = Uri.fromFile(f);mediaScanIntent.setData(contentUri);this.sendBroadcast(mediaScanIntent);}

解码一幅缩放图片

在有限的内存下,管理许多全尺寸的图片会很棘手。如果发现应用在展示了少量图片后消耗了所有内存,我们可以通过缩放图片到目标视图尺寸,之后再载入到内存中的方法,来显著降低内存的使用,下面的例子演示了这个技术

<pre name="code" class="java"><pre name="code" class="java">private void setPic() {// Get the dimensions of the Viewint targetW = mImageView.getWidth();int targetH = mImageView.getHeight();// Get the dimensions of the bitmapBitmapFactory.Options bmOptions = new BitmapFactory.Options();bmOptions.inJustDecodeBounds = true;BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);int photoW = bmOptions.outWidth;int photoH = bmOptions.outHeight;// Determine how much to scale down the imageint scaleFactor = Math.min(photoW/targetW, photoH/targetH);// Decode解码 the image file into a Bitmap位图 sized to fill the ViewbmOptions.inJustDecodeBounds = false;bmOptions.inSampleSize = scaleFactor;bmOptions.inPurgeable = true;Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);mImageView.setImageBitmap(bitmap);}

在开发图片浏览器等软件是,很多时候要显示图片的缩略图,而一般情况下,我们要将图片按照固定大小取缩略图,一般取缩略图的方法是使用BitmapFactory的decodeFile方法,然后通过传递进去 BitmapFactory.Option类型的参数进行取缩略图,在Option中,属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4。

然而,如果我们想取固定大小的缩略图就比较困难了,比如,我们想将不同大小的图片去出来的缩略图高度都为200px,而且要保证图片不失真,那怎么办?我们总不能将原始图片加载到内存中再进行缩放处理吧,要知道在移动开发中,内存是相当宝贵的,而且一张100K的图片,加载完所占用的内存何止 100K?

经过研究,发现,Options中有个属性inJustDecodeBounds,研究了一下,终于明白是什么意思了,SDK中的E文是这么说的

If set to true, the decoder will return null (no bitmap), but the out... fields will still be set, allowing the caller to query the bitmap without having to allocate the memory for its pixels.

意思就是说如果该值设为true那么将不返回实际的bitmap不给其分配内存空间而里面只包括一些解码边界信息即图片大小信息,那么相应的方法也就出来了,通过设置inJustDecodeBounds为true,获取到outHeight(图片原始高度)和 outWidth(图片的原始宽度),然后计算一个inSampleSize(缩放值),然后就可以取图片了,这里要注意的是,inSampleSize 可能小于0,必须做判断。也就是说先将Options的属性inJustDecodeBounds设为true,先获取图片的基本大小信息数据(信息没有保存在bitmap里面,而是保存在options里面),通过options.outHeight和 options. outWidth获取的大小信息以及自己想要到得图片大小计算出来缩放比例inSampleSize,然后紧接着将inJustDecodeBounds设为false,就可以根据已经得到的缩放比例得到自己想要的图片缩放图了。

详细压缩图片参考:/kf/06/134867.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。