如何在安卓系统中从相机获取位图?

3

代码:

public void startCameraActivity(){
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
            startActivityForResult(cameraIntent, 1000);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(resultCode == Activity.RESULT_OK) {
            if (requestCode == 1000){
                File photo = new File(Environment.getExternalStorageDirectory(), ".camera.jpg");
                OutputStream out = null;
                String imagePath = data.getData().getPath();
                Bitmap image = BitmapFactory.decodeFile(imagePath);
                ExifInterface exif = null;

                try {
                    exif = new ExifInterface(imagePath);

                    int exifOrientation = exif.getAttributeInt(
                            ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
                    int exifDegree = exifOrientationToDegrees(exifOrientation);
                    image = rotate(image, exifDegree);
                    photo.createNewFile();
                    out = new FileOutputStream(Environment.getExternalStorageDirectory());
                    image.compress(Bitmap.CompressFormat.PNG, 100, out);
                    out.close();
                } catch (IOException e) {
                    Toast.makeText(getContext(), "hello error", Toast.LENGTH_LONG).show();
                }
                returnUri = Uri.fromFile(photo);
            }
            Glide.with(this)
                    .load(returnUri)
                    .into(mImageview);
        }
    }

这是用于旋转图像的

public int exifOrientationToDegrees(int exifOrientation)
    {
        if(exifOrientation == ExifInterface.ORIENTATION_ROTATE_90)
        {return 90;}
        else if(exifOrientation == ExifInterface.ORIENTATION_ROTATE_180)
        {return 180;}
        else if(exifOrientation == ExifInterface.ORIENTATION_ROTATE_270)
        {return 270;}
        return 0;
    }
    public Bitmap rotate(Bitmap bitmap, int degrees)
    {
        if(degrees != 0 && bitmap != null)
        {
            Matrix m = new Matrix();
            m.setRotate(degrees, (float) bitmap.getWidth() / 2,
                    (float) bitmap.getHeight() / 2);

            try
            {
                Bitmap converted = Bitmap.createBitmap(bitmap, 0, 0,
                        bitmap.getWidth(), bitmap.getHeight(), m, true);
                if(bitmap != converted)
                {
                    bitmap.recycle();
                    bitmap = converted;
                }
            }
            catch(OutOfMemoryError ex)
            {
            }
        }
        return bitmap;
    } 

我写了一个从相机获取图片的代码。

但是相机拍摄的照片方向不正确。

于是我搜索了如何旋转图片。

但是上面的代码没有起作用。

问题出在哪里? 我该如何解决?

Android监视器显示:

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=66536, result=-1, data=Intent { act=inline-data dat=content://media/external/images/media/8464 flg=0x1 (has extras) }} to activity {~~!@.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference


Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference

编辑完整的logcat

11-03 11:21:42.060 16104-16104/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: com.keepair.www.pinair, PID: 16104
                                                   java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=66536, result=-1, data=Intent { act=inline-data dat=content://media/external/images/media/8465 flg=0x1 (has extras) }} to activity {com.keepair.www.pinair/com.keepair.www.pinair.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
                                                       at android.app.ActivityThread.deliverResults(ActivityThread.java:4173)
                                                       at android.app.ActivityThread.handleSendResult(ActivityThread.java:4216)
                                                       at android.app.ActivityThread.access$1400(ActivityThread.java:181)
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1523)
                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                       at android.os.Looper.loop(Looper.java:145)
                                                       at android.app.ActivityThread.main(ActivityThread.java:6117)
                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                       at java.lang.reflect.Method.invoke(Method.java:372)
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
                                                    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
                                                       at com.keepair.www.pinair.GreenFragment.onActivityResult(GreenFragment.java:296)
                                                       at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:165)
                                                       at android.app.Activity.dispatchActivityResult(Activity.java:6632)
                                                       at android.app.ActivityThread.deliverResults(ActivityThread.java:4169)
                                                       at android.app.ActivityThread.handleSendResult(ActivityThread.java:4216) 
                                                       at android.app.ActivityThread.access$1400(ActivityThread.java:181) 
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1523) 
                                                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                       at android.os.Looper.loop(Looper.java:145) 
                                                       at android.app.ActivityThread.main(ActivityThread.java:6117) 
                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                       at java.lang.reflect.Method.invoke(Method.java:372) 
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 
                                                       at 

com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194) 


请您展示完整的logcat异常信息。谢谢。 - undefined
我添加了 @criket_007 - undefined
image.compress 抛出了错误。看起来你从 rotate 方法中返回了 null。 - undefined
3个回答

4

这是我写的代码,你可以试一下。

public static final int PICK_USER_PROFILE_IMAGE = 1000;
public void startCameraActivity(){
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
            startActivityForResult(cameraIntent, PICK_USER_PROFILE_IMAGE);
        }
    }

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

    if (resultCode == RESULT_OK) {
        if (requestCode == Constants.PICK_USER_PROFILE_IMAGE) {
            if (resultCode == RESULT_OK) {
                Bitmap bmp = ImagePicker.getImageFromResult(this, resultCode, data);
               //your compressed rotated bitmap here

            }
        }
    }
}

以下是ImagePicker类,它有一系列方法可以帮助您完成工作。
public class ImagePicker {

private static final int DEFAULT_MIN_WIDTH_QUALITY = 400;        // min pixels
private static final String TAG = "ImagePicker";
private static final String TEMP_IMAGE_NAME = "tempImage";

public static int minWidthQuality = DEFAULT_MIN_WIDTH_QUALITY;

public static Bitmap getImageFromResult(Context context, int resultCode,
                                        Intent imageReturnedIntent) {
    Log.d(TAG, "getImageFromResult, resultCode: " + resultCode);
    Bitmap bm = null;
    File imageFile = getTempFile(context);
    if (resultCode == Activity.RESULT_OK) {
        Uri selectedImage;
        boolean isCamera = (imageReturnedIntent == null ||
                imageReturnedIntent.getData() == null ||
                imageReturnedIntent.getData().equals(Uri.fromFile(imageFile)));
        if (isCamera) {     /** CAMERA **/
            selectedImage = Uri.fromFile(imageFile);
        } else {            /** ALBUM **/
            selectedImage = imageReturnedIntent.getData();
        }
        Log.d(TAG, "selectedImage: " + selectedImage);

        bm = getImageResized(context, selectedImage);
        int rotation = getRotation(context, selectedImage, isCamera);
        bm = rotate(bm, rotation);
    }
    return bm;
}


private static Bitmap decodeBitmap(Context context, Uri theUri, int sampleSize) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = sampleSize;

    AssetFileDescriptor fileDescriptor = null;
    try {
        fileDescriptor = context.getContentResolver().openAssetFileDescriptor(theUri, "r");
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    Bitmap actuallyUsableBitmap = BitmapFactory.decodeFileDescriptor(
            fileDescriptor.getFileDescriptor(), null, options);

    Log.d(TAG, options.inSampleSize + " sample method bitmap ... " +
            actuallyUsableBitmap.getWidth() + " " + actuallyUsableBitmap.getHeight());

    return actuallyUsableBitmap;
}

/**
 * Resize to avoid using too much memory loading big images (e.g.: 2560*1920)
 **/
private static Bitmap getImageResized(Context context, Uri selectedImage) {
    Bitmap bm = null;
    int[] sampleSizes = new int[]{5, 3, 2, 1};
    int i = 0;
    do {
        bm = decodeBitmap(context, selectedImage, sampleSizes[i]);
        Log.d(TAG, "resizer: new bitmap width = " + bm.getWidth());
        i++;
    } while (bm.getWidth() < minWidthQuality && i < sampleSizes.length);
    return bm;
}


private static int getRotation(Context context, Uri imageUri, boolean isCamera) {
    int rotation;
    if (isCamera) {
        rotation = getRotationFromCamera(context, imageUri);
    } else {
        rotation = getRotationFromGallery(context, imageUri);
    }
    Log.d(TAG, "Image rotation: " + rotation);
    return rotation;
}

private static int getRotationFromCamera(Context context, Uri imageFile) {
    int rotate = 0;
    try {

        context.getContentResolver().notifyChange(imageFile, null);
        ExifInterface exif = new ExifInterface(imageFile.getPath());
        int orientation = exif.getAttributeInt(
                ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);

        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_270:
                rotate = 270;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                rotate = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                rotate = 90;
                break;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return rotate;
}

public static int getRotationFromGallery(Context context, Uri imageUri) {
    String[] columns = {MediaStore.Images.Media.ORIENTATION};
    Cursor cursor = context.getContentResolver().query(imageUri, columns, null, null, null);
    if (cursor == null) return 0;

    cursor.moveToFirst();

    int orientationColumnIndex = cursor.getColumnIndex(columns[0]);
    return cursor.getInt(orientationColumnIndex);
}


private static Bitmap rotate(Bitmap bm, int rotation) {
    if (rotation != 0) {
        Matrix matrix = new Matrix();
        matrix.postRotate(rotation);
        Bitmap bmOut = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
        return bmOut;
    }
    return bm;
}


 private static File getTempFile(Context context) {
        File imageFile = new File(context.getExternalCacheDir(), TEMP_IMAGE_NAME);
        imageFile.getParentFile().mkdirs();
        return imageFile;
    }
}

ImagePicker类具有处理图像压缩和旋转的所有方法。

希望这能帮到你。


感谢你的回答rana_sadam - undefined

1
使用预定义路径获取捕获图像的实际图像。
Intent cameraIntent = new Intent(
                android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
this.startActivityForResult(cameraIntent, 101); 

在捕获图像后,您可以在相机意图中设置的路径上获取捕获的图像。如果您不想设置预定义路径,请检查意图数据。
if (resultCode == android.app.Activity.RESULT_OK && requestCode == 101) {
                try {

                    path_mm = "Onsuccess_resultcode";
                    generateNoteOnSD("photo34.txt", path_mm);
                    Bitmap photo = null;
                    if (data == null) {
                    //get Bitmap  here.
                    } 
               else {
                    Uri u1 = data.getData();
                    //get uri and find actual path on that uri.
                     }
                     }catch(Exception ex)
                     {}}

0
首先,也许你应该检查一下这行代码:
if(degrees != 0 && bitmap != null)

如果这行代码为假,将返回"null",并且监视器会显示错误信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接