繁体   English   中英

Android - 如何从相机或图库拍摄照片

[英]Android - How to take a picture from camera or gallery

我想让用户从相机或设备中的现有图片(图库或其他)拍摄照片。 我怎样才能做到这一点?

我已经实现了下面的解决方案,这似乎工作正常,但文档很混乱,所以我想知道是否有更好的解决方案。

另外,请查看此相关帖子。 在那里,您将看到如何获取图像路径或位图: 以编程方式从Android的内置Gallery应用程序中获取/选择图像

因此,在我的解决方案中,您将创建一个TakePictureHelper对象并执行以下操作。

假设您显示一个对话框,用户可以选择“相机”或“其他”。 当用户选择一个选项时,您可以调用takeFromCamera()takeFromOther() 拍摄(或不拍摄)照片时,将调用onActivityResult()方法。 在那里你会调用retrievePicture ,它将返回图片的Uri,如果没有拍照,则返回null。

如果我不清楚,请告诉我你的想法,分享想法或问我什么。

非常感谢你!

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TakePictureHelper {

    public final static int REQUEST_CAMERA = 1;
    public final static int REQUEST_OTHER = 2;

    private Uri cameraImageUri;

    /**
     * Request picture from camera using the given title
     */
    public void takeFromCamera(Activity activity, String title)
    {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File cameraImageOutputFile = new File(
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                createCameraImageFileName());
        cameraImageUri = Uri.fromFile(cameraImageOutputFile);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraImageUri);
        activity.startActivityForResult(Intent.createChooser(intent, title), REQUEST_CAMERA);
    }

    /**
     * Request picture from any app (gallery or whatever) using the given title
     */
    public void takeFromOther(Activity activity, String title)
    {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");
        activity.startActivityForResult(Intent.createChooser(intent, title), REQUEST_OTHER);
    }

    /**
     * Retrieve the picture, taken from camera or gallery.
     *
     * @return the picture Uri, or null if no picture was taken.
     */
    public Uri retrievePicture(Activity activity, int requestCode, int resultCode, Intent data)
    {
        Uri result = null;

        if (resultCode == Activity.RESULT_OK) {

            if (requestCode == REQUEST_OTHER) {
                result = data.getData();
            } else if (requestCode == REQUEST_CAMERA) {
                result = cameraImageUri;
            }
        }

        return result;
    }

    private String createCameraImageFileName() {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        return timeStamp + ".jpg";
    }
}

基于@ yurezcv的回答,这是我想出的(最重要的是如何在onActivityResult中检索图像):

private List<File> cameraImageFiles;

private void popImageChooser(){
    // Camera.
    final List<Intent> cameraIntents = new ArrayList<Intent>();
    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    final PackageManager packageManager = getPackageManager();
    final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);

    cameraImageFiles = new ArrayList<File>();

    int i=0;
    for(ResolveInfo res : listCam) {
        final String packageName = res.activityInfo.packageName;
        final Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
        intent.setPackage(packageName);
        intent.putExtra(MediaStore.MEDIA_IGNORE_FILENAME, ".nomedia");

        File cameraImageOutputFile = new File(
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                createCameraImageFileName());
        cameraImageFiles.add(cameraImageOutputFile);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraImageFiles.get(i)));
        i++;

        cameraIntents.add(intent);
    }

    // Filesystem.
    final Intent galleryIntent = new Intent();
    galleryIntent.setType("image/*");
    galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

    // Chooser of filesystem options.
    final Intent chooserIntent = Intent.createChooser(galleryIntent, getString(R.string.attach_images_title));

    // Add the camera options.
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
    startActivityForResult(chooserIntent, ACTIVITY_REQUEST_CODE_IMAGE);
}


protected void onActivityResult(int requestCode, int resultCode, 
           Intent imageReturnedIntent) {
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent); 

    switch(requestCode) { 
    case ACTIVITY_REQUEST_CODE_IMAGE:
        if(resultCode == RESULT_OK){

            Uri uri = null;
            if(imageReturnedIntent == null){   //since we used EXTRA_OUTPUT for camera, so it will be null

                for(int i=0;i<cameraImageFiles.size();i++){
                    if(cameraImageFiles.get(i).exists()){
                        uri = Uri.fromFile(cameraImageFiles.get(i));
                        break;
                    }
                }
                Log.d("attachimage", "from camera: "+uri);
            }
            else {  // from gallery
                uri = imageReturnedIntent.getData();
                Log.d("attachimage", "from gallery: "+uri.toString());
            }

            if(uri != null){
                attachImage(uri);
            }
        }
    }
}

这个解决方案对我有用:

private void addPhoto() {   
       // Camera.
    final List<Intent> cameraIntents = new ArrayList<Intent>();
    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);     
    final PackageManager packageManager = getPackageManager();
    final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
    for(ResolveInfo res : listCam) {
        final String packageName = res.activityInfo.packageName;
        final Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
        intent.setPackage(packageName);
        intent.putExtra(MediaStore.MEDIA_IGNORE_FILENAME, ".nomedia");

        cameraIntents.add(intent);
    }

    // Filesystem.
    final Intent galleryIntent = new Intent();
    galleryIntent.setType("image/*");
    galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

    // Chooser of filesystem options.
    final Intent chooserIntent = Intent.createChooser(galleryIntent, getString(R.string.add_new));

    // Add the camera options.
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
    startActivityForResult(chooserIntent, YOUR_REQUEST_CODE);
}

它创建一个意图对话框,其中包含来自摄像机,文件系统等的所选图像的所有可能变体

Hay un detalle que no se ha dicho y es que actualmente el tema delaorientacióndelacámaraesun desastre cuando lo que se hace es guardar la captura y luego leerla de disco para mostrarla。 Estoesasíporquelos fabricantes,como HTC,Samsung等等,没有任何标准可供选择。 En este caso,puede(y depende del dispositivo),ser necesario corregir la imagen usandolainformaciónEXIFde la misma para que no se muestre rotada por ejemplo,en un ImageView。

Si la imagen delacámaranola guardamos sino que en la vuelta leemos del Bundle los datos guardados en la key“data”,la imagensemostrarábien。

Otra cosa queyoharíasiguardamos la foto en disco,es hacer que esta se vea enlagaleríaparaque el usuario la pueda ver y borrar directamente(ver MediaScannerConnectionClient)

他喜欢和他妈妈一起聊天。 Permite hacerlo bien porlagaleríaó,tomando una captura conlacámara。 para algunas tareas他usadolalibreríapúblicenGitHub https://github.com/javocsoft/javocsoft-toolbox/

package com.example.getpicture;

import java.io.File;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
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 es.javocsoft.android.lib.toolbox.ToolBox;
import es.javocsoft.android.lib.toolbox.media.MediaScannerNotifier;

public class MainActivity extends Activity {

private final int PICTURE_TAKEN_FROM_CAMERA = 1;
private final int PICTURE_TAKEN_FROM_GALLERY = 2;

private Button btncamera = null;
private Button btngallery = null;
private ImageView pictureZone = null;
private boolean storeImage = false;
private File outFile = null;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    pictureZone = (ImageView)findViewById(R.id.pictureZone);
    btncamera = (Button)findViewById(R.id.btncamera);
    btngallery = (Button)findViewById(R.id.btngallery);


    addEvents();
}


private void addEvents(){
    btncamera.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            getPictureFromCamera();         
        }
    });

    btngallery.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            getPictureFromGallery();            
        }
    });
}   

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    Bitmap takenPictureData = null;

    switch(requestCode){

        case PICTURE_TAKEN_FROM_CAMERA:             
            if(resultCode==Activity.RESULT_OK) {
                takenPictureData = handleResultFromCamera(data);
            }               
            break;
        case PICTURE_TAKEN_FROM_GALLERY:                
            if(resultCode==Activity.RESULT_OK) {
                takenPictureData = handleResultFromChooser(data);                   
            }
            break;          
    }

    //And show the result in the image view.
    if(takenPictureData!=null){
        pictureZone.setImageBitmap(takenPictureData);
    }       
}


//AUXILIAR

private Bitmap handleResultFromChooser(Intent data){
    Bitmap takenPictureData = null;

    Uri photoUri = data.getData();
    if (photoUri != null){
        try {
            //We get the file path from the media info returned by the content resolver
            String[] filePathColumn = {MediaStore.Images.Media.DATA};
            Cursor cursor = getContentResolver().query(photoUri, filePathColumn, null, null, null); 
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String filePath = cursor.getString(columnIndex);
            cursor.close();

            takenPictureData = ToolBox.media_getBitmapFromFile(new File(filePath));

        }catch(Exception e){
            ToolBox.dialog_showToastAlert(this, "Error getting selected image.", false);
        }
    }

    return takenPictureData;
}

private Bitmap handleResultFromCamera(Intent data){
    Bitmap takenPictureData = null;

    if(data!=null){
        //Android sets the picture in extra data.
        Bundle extras = data.getExtras();
        if(extras!=null && extras.get("data")!=null){
            takenPictureData = (Bitmap) extras.get("data");
        }
    }else{
        //If we used EXTRA_OUTPUT we do not have the data so we get the image
        //from the output.
        try{
            takenPictureData = ToolBox.media_getBitmapFromFile(outFile);
            takenPictureData = ToolBox.media_correctImageOrientation(outFile.getAbsolutePath());
        }catch(Exception e){
            ToolBox.dialog_showToastAlert(this, "Error getting saved taken picture.", false);
        }
    }

    if(storeImage){
        //We add the taken picture file to the gallery so user can see the image directly                   
        new MediaScannerNotifier(this,outFile.getAbsolutePath(),"image/*", false);
    }

    return takenPictureData;
}

private void getPictureFromCamera(){
    boolean cameraAvailable = ToolBox.device_isHardwareFeatureAvailable(this, PackageManager.FEATURE_CAMERA);
    if(cameraAvailable && 
        ToolBox.system_isIntentAvailable(this, MediaStore.ACTION_IMAGE_CAPTURE)){

        Intent takePicIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        //We prepare the intent to store the taken picture
        try{
            File outputDir = ToolBox.storage_getExternalPublicFolder(Environment.DIRECTORY_PICTURES, "testApp", true);
            outFile = ToolBox.storage_createUniqueFileName("cameraPic", ".jpg", outputDir);

            takePicIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(outFile));             
            storeImage = true;
        }catch(Exception e){
            ToolBox.dialog_showToastAlert(this, "Error setting output destination.", false);
        }

        startActivityForResult(takePicIntent, PICTURE_TAKEN_FROM_CAMERA);
    }else{
        if(cameraAvailable){
            ToolBox.dialog_showToastAlert(this, "No application that can receive the intent camera.", false);
        }else{
            ToolBox.dialog_showToastAlert(this, "No camera present!!", false);
        }
    }
}

private void getPictureFromGallery(){
    /*
    //This allows to select the application to use when selecting an image.
    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
    i.setType("image/*");
    startActivityForResult(Intent.createChooser(i, "Escoge una foto"), PICTURE_TAKEN_FROM_GALLERY);
    */

    //This takes images directly from gallery
    Intent gallerypickerIntent = new Intent(Intent.ACTION_PICK);
    gallerypickerIntent.setType("image/*");
    startActivityForResult(gallerypickerIntent, PICTURE_TAKEN_FROM_GALLERY); 
}

}

El布局es:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="#f2f2f2"    
tools:context=".MainActivity" >

<ImageView
    android:id="@+id/pictureZone"
    android:layout_width="280dp"
    android:layout_height="280dp"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"

    android:src="@drawable/ic_launcher" />

<Button
    android:id="@+id/btncamera"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="36dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:text="Camera" />

<Button
    android:id="@+id/btngallery"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"
    android:text="Pick it" />

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_above="@+id/btngallery"
    android:layout_centerHorizontal="true"
    android:text="Choose an option"
    android:textStyle="bold"
    android:textAppearance="?android:attr/textAppearanceMedium" />

Yporúltimowenel hace falta como no,los permisos adecuados:

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

Un saludo。

  1. 在您的布局中创建一个按钮(通过单击此按钮将打开一个对话框,您可以在其中选择是选择相机还是广场)。

  2. 现在初始化其类中的按钮:

    - 在onCreate之前:

    Button btu;

    - 在onCreate里面:

    btu = (Button) findViewById(R.id.BtUp);

  3. 方法称相机和画廊

- 在onCreate启动之前

int CAMERA_REQUEST = 1;

- 方法调用相机

public void callCamera() {
    Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    cameraIntent.putExtra("crop", "true");
    cameraIntent.putExtra("aspectX", 0);
    cameraIntent.putExtra("aspectY", 0);
    cameraIntent.putExtra("outputX", 200);
    cameraIntent.putExtra("outputY", 150);
    startActivityForResult(cameraIntent, CAMERA_REQUEST);
}

- 方法调用库

public void callGallery() {
    Intent intent = new Intent(Intent.ACTION_PICK,
                               MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(intent,0);
}
  1. 创建一个方法来显示AlertDialog,它似乎选择:

     public void showAlertDialog(Context context) { this.context = context; final String items[] = {getString(R.string.TextTakeCam), getString(R.string.TextTakeGal)}; AlertDialog.Builder ab = new AlertDialog.Builder(MainActivity.this); ab.setTitle(getString(R.string.TextTitleDia)); AlertDialog.Builder builder = ab.setItems(items, new DialogInterface.OnClickListener() { public void onClick(DialogInterface d, int choice) { if (choice == 0) { callCamera(); } else if (choice == 1) { image.setVisibility(View.INVISIBLE); callGallery(); } }}); ab.show(); 

    }

  2. 在按钮中调用AlertDialog

     btu.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String title = getString(R.string.TextUp); String msg = getString(R.string.TextUp2); showAlertDialog2(MainActivity.this,title,msg,true); //maneger.UpdateC(edname.getText().toString(),edfoto.getText().toString(),ednum. getText().toString()); } }); 

在AndroidManifest.xml中

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

我找到了一种更好,更简单的方法从相机或画廊拍照,即使用这个库https://android-arsenal.com/details/1/3623

您可以点击上面的链接或按照以下步骤操作:

在项目中使用此库的步骤如下:

  1. 向Gradle添加依赖项:

    编译'com.frosquivel:magicalcamera:4.4'

  2. 实施守则:

    PermissionGranted permissionGranted = new PermissionGranted(this); MagicalCamera magicalCamera = new MagicalCamera(this,permissionGranted); //参数this,是当前活动//拍照的权限,如果用户检查deny permissionGranted.checkCameraPermission(),则为false; //用于在设备内存中搜索和写入照片//正常或SD内存permissionGranted.checkReadExternalPermission(); permissionGranted.checkWriteExternalPermission();

  3. 打电话从相机拍照:

    magicalCamera.takePhoto();

  4. 致电从图库中选择照片:

    magicalCamera.selectedPicture( “my_header_name”);

  5. 覆盖OnActivityResult(); 获取位图和路径的方法:

     public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); magicalCamera.resultPhoto(requestCode, resultCode, data);//with this form you obtain the bitmap Bitmap bitmap = magicalCamera.getPhoto(); imageView.setImageBitmap(bitmap); //if you need path of bitmap use this code String path = magicalCamera.savePhotoInMemoryDevice(magicalCamera.getPhoto(),"myPhotoName","myDirectoryName", MagicalCamera.JPEG, true); 

    if(path!= null){Toast.makeText(MainActivity.this,“照片保存在设备中,请检查此路径:”+ path,Toast.LENGTH_SHORT).show(); } else {Toast.makeText(MainActivity.this,“抱歉你的照片不要写在devide,请联系fabian7593 @gmail并说出这个错误”,Toast.LENGTH_SHORT).show(); }}

有关更多详细信息,请参阅上面的链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM