Захват изображения с камеры и отображение в действии

Я хочу написать модуль, где одним нажатием кнопки открывается камера, и я могу щелкнуть и захватить изображение. Если мне не нравится изображение, я могу удалить его и нажать еще одно изображение, а затем выбрать изображение, и оно должно вернуться назад и отобразить это изображение в действии.

Вот пример активности, который запустит приложение камеры, а затем извлечет изображение и отобразит его.

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; private static final int MY_CAMERA_PERMISSION_CODE = 100; @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) { if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_CAMERA_PERMISSION_CODE); } else { Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(cameraIntent, CAMERA_REQUEST); } } }); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == MY_CAMERA_PERMISSION_CODE) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(this, "camera permission granted", Toast.LENGTH_LONG).show(); Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(cameraIntent, CAMERA_REQUEST); } else { Toast.makeText(this, "camera permission denied", Toast.LENGTH_LONG).show(); } } 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); } } } 

Обратите внимание, что приложение камеры само по себе дает вам возможность просматривать / перехватывать изображение, и после того, как изображение будет принято, это отобразит его действие.

Вот макет, который использует вышеуказанная деятельность. Это просто LinearLayout, содержащий кнопку с кнопкой id1 и ImageView с id imageview1:

      

И еще одну деталь, обязательно добавьте:

  

и если камера не является обязательной для вашего приложения. убедитесь, что в запросе установлено значение false. как это

  

к вашему manifest.xml.

Мне потребовалось несколько часов, чтобы заставить это работать. Код это почти копия-паста с сайта developer.android.com с незначительной разницей.

Запросите это разрешение на AndroidManifest.xml :

  

В своей Activity начните с определения этого:

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

Затем запустите это Intent в onClick :

 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 .

Capture photo + Выбрать из галереи:

  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); } } 

Я знаю, что это довольно старый stream, но все эти решения не завершены и не работают на некоторых устройствах, когда пользователь поворачивает камеру, потому что данные в onActivityResult равны нулю. Итак, вот решение, которое я тестировал на множестве устройств и до сих пор не сталкивался с какой-либо проблемой.

Сначала объявите свою переменную Uri в своей деятельности:

 private Uri uriFilePath; 

Затем создайте свою временную папку для хранения захваченного изображения и сделайте намерение захватить изображение камерой:

 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); } 

После этого вы всегда должны восстановить свой uri в методе onCreate:

 @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")); } } } 

И вот последняя часть, чтобы получить ваш Uri inActivityResult:

 @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 Не забудьте добавить разрешения для камеры и Ext. хранения в вашем манифесте.

Вам нужно прочитать о Камере . (Я думаю, что нужно делать то, что вы хотите, вам нужно сохранить текущий образ в вашем приложении, выбрать его / удалить, а затем вызвать камеру, чтобы повторить попытку, а не повторять попытку прямо внутри камеры.)

Вот код, который я использовал для Capturing and Saving Camera Image, затем отображает его в режиме просмотра изображений. Вы можете использовать в соответствии с вашими потребностями.

Вы должны сохранить изображение камеры в определенное место, а затем извлечь из этого места, а затем преобразовать его в байтовый массив.

Вот способ открытия захвата активности изображения камеры.

 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(); } } } 

Вот метод getBitmap (), используемый в onActivityResult (). Я сделал все улучшения производительности, которые могут быть возможны при получении растрового изображения изображения с камеры.

 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; } } 

Надеюсь, поможет!

В работе:

 @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   

в manifest.xml:

    

Захватите фото с камеры + выберите изображение из галереи и установите его на задний план макета или изображения. Вот пример кода.

 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    

Вы можете использовать пользовательскую камеру с миниатюрным изображением. Вы можете посмотреть мой проект .

Вот полный код:

 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); } } } 

Не забудьте также добавить разрешения для камеры.

Давайте будем гением компьютера.