从相机捕获图像并在活动中显示

我想写一个模块,点击相机打开的button,我可以点击并捕捉图像。 如果我不喜欢该图像,我可以删除它,然后单击一个图像,然后select图像,它应该返回并在活动中显示该图像。

以下是一个示例活动,将启动相机应用程序,然后检索图像并显示它。

package edu.gvsu.cis.masl.camerademo; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageView; public class MyCameraActivity extends Activity { private static final int CAMERA_REQUEST = 1888; private ImageView imageView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.imageView = (ImageView)this.findViewById(R.id.imageView1); Button photoButton = (Button) this.findViewById(R.id.button1); photoButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(cameraIntent, CAMERA_REQUEST); } }); } protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) { Bitmap photo = (Bitmap) data.getExtras().get("data"); imageView.setImageBitmap(photo); } } } 

请注意,相机应用程序本身为您提供了查看/重拍图像的function,一旦图像被接受,活动就会显示它。

以上是上述活动使用的布局。 它只是一个LinearLayout,它包含一个带有id button1的button和一个带有id imageview1的ImageView:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/photo"></Button> <ImageView android:id="@+id/imageView1" android:layout_height="wrap_content" android:src="@drawable/icon" android:layout_width="wrap_content"></ImageView> </LinearLayout> 

最后一个细节,一定要补充:

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

如果相机是您的应用程序function的可选项。 请确保将权限设置为false。 喜欢这个

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

到你的manifest.xml。

我花了几个小时才能完成这项工作。 这个代码几乎是来自developer.android.com的一个复制粘贴,只有很小的差别。

AndroidManifest.xml请求这个权限:

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

在你的Activity ,首先定义这个:

 static final int REQUEST_IMAGE_CAPTURE = 1; private Bitmap mImageBitmap; private String mCurrentPhotoPath; private ImageView mImageView; 

然后在onClick激发这个Intent

 Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (cameraIntent.resolveActivity(getPackageManager()) != null) { // Create the File where the photo should go File photoFile = null; try { photoFile = createImageFile(); } catch (IOException ex) { // Error occurred while creating the File Log.i(TAG, "IOException"); } // Continue only if the File was successfully created if (photoFile != null) { cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile)); startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE); } } 

添加以下支持方法:

 private File createImageFile() throws IOException { // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES); File image = File.createTempFile( imageFileName, // prefix ".jpg", // suffix storageDir // directory ); // Save a file: path for use with ACTION_VIEW intents mCurrentPhotoPath = "file:" + image.getAbsolutePath(); return image; } 

然后收到结果:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { try { mImageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(mCurrentPhotoPath)); mImageView.setImageBitmap(mImageBitmap); } catch (IOException e) { e.printStackTrace(); } } } 

使其工作的是MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(mCurrentPhotoPath)) ,它与developer.android.com中的代码不同。 原来的代码给了我一个FileNotFoundException

捕捉照片+从照片库中select:

  a = (ImageButton)findViewById(R.id.imageButton1); a.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { selectImage(); } }); } private File savebitmap(Bitmap bmp) { String extStorageDirectory = Environment.getExternalStorageDirectory().toString(); OutputStream outStream = null; // String temp = null; File file = new File(extStorageDirectory, "temp.png"); if (file.exists()) { file.delete(); file = new File(extStorageDirectory, "temp.png"); } try { outStream = new FileOutputStream(file); bmp.compress(Bitmap.CompressFormat.PNG, 100, outStream); outStream.flush(); outStream.close(); } catch (Exception e) { e.printStackTrace(); return null; } return file; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } private void selectImage() { final CharSequence[] options = { "Take Photo", "Choose from Gallery","Cancel" }; AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setTitle("Add Photo!"); builder.setItems(options, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int item) { if (options[item].equals("Take Photo")) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg"); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f)); //pic = f; startActivityForResult(intent, 1); } else if (options[item].equals("Choose from Gallery")) { Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, 2); } else if (options[item].equals("Cancel")) { dialog.dismiss(); } } }); builder.show(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { if (requestCode == 1) { //h=0; File f = new File(Environment.getExternalStorageDirectory().toString()); for (File temp : f.listFiles()) { if (temp.getName().equals("temp.jpg")) { f = temp; File photo = new File(Environment.getExternalStorageDirectory(), "temp.jpg"); //pic = photo; break; } } try { Bitmap bitmap; BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(), bitmapOptions); a.setImageBitmap(bitmap); String path = android.os.Environment .getExternalStorageDirectory() + File.separator + "Phoenix" + File.separator + "default"; //p = path; f.delete(); OutputStream outFile = null; File file = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg"); try { outFile = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG, 85, outFile); //pic=file; outFile.flush(); outFile.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } } else if (requestCode == 2) { Uri selectedImage = data.getData(); // h=1; //imgui = selectedImage; String[] filePath = { MediaStore.Images.Media.DATA }; Cursor c = getContentResolver().query(selectedImage,filePath, null, null, null); c.moveToFirst(); int columnIndex = c.getColumnIndex(filePath[0]); String picturePath = c.getString(columnIndex); c.close(); Bitmap thumbnail = (BitmapFactory.decodeFile(picturePath)); Log.w("path of image from gallery......******************.........", picturePath+""); a.setImageBitmap(thumbnail); } } 

你需要阅读关于相机 。 (我认为要做你想做的事情,你必须把当前的图像保存到你的应用程序,在那里做select/删除,然后调用摄像机重试,而不是直接在摄像机内重试。

这里是我用于捕获和保存相机图像,然后显示它到imageview的代码。 你可以根据你的需要使用。

您必须将相机图像保存到特定的位置,然后从该位置获取,然后将其转换为字节数组。

这是打开捕捉摄像头图像活动的方法。

 private static final int CAMERA_PHOTO = 111; private Uri imageToUploadUri; private void captureCameraImage() { Intent chooserIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); File f = new File(Environment.getExternalStorageDirectory(), "POST_IMAGE.jpg"); chooserIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f)); imageToUploadUri = Uri.fromFile(f); startActivityForResult(chooserIntent, CAMERA_PHOTO); } 

那么你的onActivityResult()方法应该是这样的。

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == CAMERA_PHOTO && resultCode == Activity.RESULT_OK) { if(imageToUploadUri != null){ Uri selectedImage = imageToUploadUri; getContentResolver().notifyChange(selectedImage, null); Bitmap reducedSizeBitmap = getBitmap(imageToUploadUri.getPath()); if(reducedSizeBitmap != null){ ImgPhoto.setImageBitmap(reducedSizeBitmap); Button uploadImageButton = (Button) findViewById(R.id.uploadUserImageButton); uploadImageButton.setVisibility(View.VISIBLE); }else{ Toast.makeText(this,"Error while capturing Image",Toast.LENGTH_LONG).show(); } }else{ Toast.makeText(this,"Error while capturing Image",Toast.LENGTH_LONG).show(); } } } 

这里是onActivityResult()中使用的getBitmap()方法。 在获取相机捕获图像位图的同时,我做了所有可能的性能改进。

 private Bitmap getBitmap(String path) { Uri uri = Uri.fromFile(new File(path)); InputStream in = null; try { final int IMAGE_MAX_SIZE = 1200000; // 1.2MP in = getContentResolver().openInputStream(uri); // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(in, null, o); in.close(); int scale = 1; while ((o.outWidth * o.outHeight) * (1 / Math.pow(scale, 2)) > IMAGE_MAX_SIZE) { scale++; } Log.d("", "scale = " + scale + ", orig-width: " + o.outWidth + ", orig-height: " + o.outHeight); Bitmap b = null; in = getContentResolver().openInputStream(uri); if (scale > 1) { scale--; // scale to max possible inSampleSize that still yields an image // larger than target o = new BitmapFactory.Options(); o.inSampleSize = scale; b = BitmapFactory.decodeStream(in, null, o); // resize to desired dimensions int height = b.getHeight(); int width = b.getWidth(); Log.d("", "1th scale operation dimenions - width: " + width + ", height: " + height); double y = Math.sqrt(IMAGE_MAX_SIZE / (((double) width) / height)); double x = (y / height) * width; Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, (int) x, (int) y, true); b.recycle(); b = scaledBitmap; System.gc(); } else { b = BitmapFactory.decodeStream(in); } in.close(); Log.d("", "bitmap size - width: " + b.getWidth() + ", height: " + b.getHeight()); return b; } catch (IOException e) { Log.e("", e.getMessage(), e); return null; } } 

希望它有帮助!

我知道这是一个相当古老的线程,但所有这些解决scheme都没有完成,并且在用户旋转摄像头时不能在某些设备上工作,因为onActivityResult中的数据为空。 所以这里是我在很多设备上testing过的解决scheme,到目前为止还没有遇到任何问题。

首先在你的活动中声明你的Urivariables:

 private Uri uriFilePath; 

然后创build您的临时文件夹存储捕获的图像,并意图通过摄像头捕获图像:

 PackageManager packageManager = getActivity().getPackageManager(); if (packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)) { File mainDirectory = new File(Environment.getExternalStorageDirectory(), "MyFolder/tmp"); if (!mainDirectory.exists()) mainDirectory.mkdirs(); Calendar calendar = Calendar.getInstance(); uriFilePath = Uri.fromFile(new File(mainDirectory, "IMG_" + calendar.getTimeInMillis())); intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, uriFilePath); startActivityForResult(intent, 1); } 

现在,这里是最重要的事情之一,你必须将你的uriFilePath保存在onSaveInstanceState中,因为如果你没有这样做,并且用户在使用相机的时候旋转了他的设备,你的uri将是空的。

 @Override protected void onSaveInstanceState(Bundle outState) { if (uriFilePath != null) outState.putString("uri_file_path", uriFilePath.toString()); super.onSaveInstanceState(outState); } 

之后,你应该总是在你的onCreate方法中恢复你的uri:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { if (uriFilePath == null && savedInstanceState.getString("uri_file_path") != null) { uriFilePath = Uri.parse(savedInstanceState.getString("uri_file_path")); } } } 

最后一部分是在onActivityResult中获得你的Uri:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { if (requestCode == 1) { String filePath = uriFilePath.getPath(); // Here is path of your captured image, so you can create bitmap from it, etc. } } } 

PS不要忘记为Camera和Ext添加权限。 存储写入您的清单。

在活动中:

 @Override protected void onCreate(Bundle savedInstanceState) { image = (ImageView) findViewById(R.id.imageButton); image.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { SimpleDateFormat sdfPic = new SimpleDateFormat(DATE_FORMAT); currentDateandTime = sdfPic.format(new Date()).replace(" ", ""); File imagesFolder = new File(IMAGE_PATH, currentDateandTime); imagesFolder.mkdirs(); Random generator = new Random(); int n = 10000; n = generator.nextInt(n); String fname = IMAGE_NAME + n + IMAGE_FORMAT; File file = new File(imagesFolder, fname); outputFileUri = Uri.fromFile(file); cameraIntent= new Intent( android.provider.MediaStore.ACTION_IMAGE_CAPTURE); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); startActivityForResult(cameraIntent, CAMERA_DATA); }catch(Exception e) { e.printStackTrace(); } } }); @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch(requestCode) { case CAMERA_DATA : final int IMAGE_MAX_SIZE = 300; try { // Bitmap bitmap; File file = null; FileInputStream fis; BitmapFactory.Options opts; int resizeScale; Bitmap bmp; file = new File(outputFileUri.getPath()); // This bit determines only the width/height of the // bitmap // without loading the contents opts = new BitmapFactory.Options(); opts.inJustDecodeBounds = true; fis = new FileInputStream(file); BitmapFactory.decodeStream(fis, null, opts); fis.close(); // Find the correct scale value. It should be a power of // 2 resizeScale = 1; if (opts.outHeight > IMAGE_MAX_SIZE || opts.outWidth > IMAGE_MAX_SIZE) { resizeScale = (int) Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE/ (double) Math.max(opts.outHeight, opts.outWidth)) / Math.log(0.5))); } // Load pre-scaled bitmap opts = new BitmapFactory.Options(); opts.inSampleSize = resizeScale; fis = new FileInputStream(file); bmp = BitmapFactory.decodeStream(fis, null, opts); Bitmap getBitmapSize = BitmapFactory.decodeResource( getResources(), R.drawable.male); image.setLayoutParams(new RelativeLayout.LayoutParams( 200,200));//(width,height); image.setImageBitmap(bmp); image.setRotation(90); fis.close(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.JPEG, 70, baos); imageByte = baos.toByteArray(); break; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 

在layout.xml中:

 enter code here <RelativeLayout android:id="@+id/relativeLayout2" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:id="@+id/imageButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/XXXXXXX" android:textAppearance="?android:attr/textAppearanceSmall" /> 

在manifest.xml中:

  <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> 

从相机捕捉照片+从图库中挑选图像,并将其设置为布局或图像视图的背景。 这里是示例代码。

 import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.GridView; import android.widget.ImageView; import android.widget.LinearLayout; public class Post_activity extends Activity { final int TAKE_PICTURE = 1; final int ACTIVITY_SELECT_IMAGE = 2; ImageView openCameraOrGalleryBtn,cancelBtn; LinearLayout backGroundImageLinearLayout; public void onCreate(Bundle savedBundleInstance) { super.onCreate(savedBundleInstance); overridePendingTransition(R.anim.slide_up,0); setContentView(R.layout.post_activity); backGroundImageLinearLayout=(LinearLayout)findViewById(R.id.background_image_linear_layout); cancelBtn=(ImageView)findViewById(R.id.cancel_icon); openCameraOrGalleryBtn=(ImageView)findViewById(R.id.camera_icon); openCameraOrGalleryBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub selectImage(); } }); cancelBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub overridePendingTransition(R.anim.slide_down,0); finish(); } }); } public void selectImage() { final CharSequence[] options = { "Take Photo", "Choose from Gallery","Cancel" }; AlertDialog.Builder builder = new AlertDialog.Builder(Post_activity.this); builder.setTitle("Add Photo!"); builder.setItems(options,new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub if(options[which].equals("Take Photo")) { Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(cameraIntent, TAKE_PICTURE); } else if(options[which].equals("Choose from Gallery")) { Intent intent=new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, ACTIVITY_SELECT_IMAGE); } else if(options[which].equals("Cancel")) { dialog.dismiss(); } } }); builder.show(); } public void onActivityResult(int requestcode,int resultcode,Intent intent) { super.onActivityResult(requestcode, resultcode, intent); if(resultcode==RESULT_OK) { if(requestcode==TAKE_PICTURE) { Bitmap photo = (Bitmap)intent.getExtras().get("data"); Drawable drawable=new BitmapDrawable(photo); backGroundImageLinearLayout.setBackgroundDrawable(drawable); } else if(requestcode==ACTIVITY_SELECT_IMAGE) { Uri selectedImage = intent.getData(); String[] filePath = { MediaStore.Images.Media.DATA }; Cursor c = getContentResolver().query(selectedImage,filePath, null, null, null); c.moveToFirst(); int columnIndex = c.getColumnIndex(filePath[0]); String picturePath = c.getString(columnIndex); c.close(); Bitmap thumbnail = (BitmapFactory.decodeFile(picturePath)); Drawable drawable=new BitmapDrawable(thumbnail); backGroundImageLinearLayout.setBackgroundDrawable(drawable); } } } public void onBackPressed() { super.onBackPressed(); //overridePendingTransition(R.anim.slide_down,0); } } Add these permission in Androidmenifest.xml file <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.CAMERA"/> 

您可以使用带缩略图的自定义相机。 你可以看我的项目 。

这里是完整的代码:

 package com.example.cameraa; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageView; public class MainActivity extends Activity { Button btnTackPic; Uri photoPath; ImageView ivThumbnailPhoto; static int TAKE_PICTURE = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Get reference to views btnTackPic = (Button) findViewById(R.id.bt1); ivThumbnailPhoto = (ImageView) findViewById(R.id.imageView1); btnTackPic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(cameraIntent, TAKE_PICTURE); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { if (requestCode == TAKE_PICTURE && resultCode == RESULT_OK) { Bitmap photo = (Bitmap)intent.getExtras().get("data"); ivThumbnailPhoto.setImageBitmap(photo); ivThumbnailPhoto.setVisibility(View.VISIBLE); } } } 

记得也要为相机添加权限。