ImageView setImageBitmap无法在某些设备上运行

时间:2013-11-13 07:15:30

标签: android imageview android-camera

我正在练习Camera API,我为此做了以下工作:

一个。为捕获的图像(对于startActivityForResult

设置目录

湾设置位图,以便一旦保存在应用程序本身中就可以显示图像。

以下是以下代码:

设置目录。

private static File getOutputMediaFile(int type) {

    // External sdcard location
    File mediaStorageDir = new File(
            Environment
                    .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            IMAGE_DIRECTORY_NAME);
    // Create the storage directory if it does not exist
    if (!mediaStorageDir.exists()) {
        if (!mediaStorageDir.mkdirs()) {
            Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
                    + IMAGE_DIRECTORY_NAME + " directory");
            return null;
        }
    }
    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
            Locale.getDefault()).format(new Date());
    File mediaFile;
    if (type == MEDIA_TYPE_IMAGE) {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator
                + "IMG_" + timeStamp + ".jpg");
    } else {
        return null;
    }

    return mediaFile;
}

应用程序中的全局变量

// Activity request codes
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
public static final int MEDIA_TYPE_IMAGE = 1;

// directory name to store the captured images
private static final String IMAGE_DIRECTORY_NAME = "my_camera_app";

private Uri fileUri;

// Views
ImageView photo;
Button camera;

相机实施逻辑

// Use camera function
private void captureImage() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

    // start the image capture Intent
    startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            // Successfully captured the image
            // display in imageview
            previewImage();
        } else {
            // failed to capture image
            Toast.makeText(getApplicationContext(),
                    "Sorry! Failed to capture image", Toast.LENGTH_SHORT)
                    .show();
        }
    }
}

private void previewImage() {
    try {
        // Bitmap factory
        BitmapFactory.Options options = new BitmapFactory.Options();

        // Downsizing image as it throws OutOfMemory exception for larger
        // images
        options.inSampleSize = 3;

        final Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(),
                options);

        photo.setImageBitmap(bitmap);

    } catch (NullPointerException e) {
        e.printStackTrace();
    }
}

我遇到的问题是......对于我测试应用程序的某些设备,该应用程序显示了所拍摄图像的空白预览,而在其他设备中该应用程序运行良好。

为什么我收到空白反馈?在某些情况下,保存图像时,用户不会被定向到我的应用程序,而是用户卡在相机应用程序中。

请帮忙。

6 个答案:

答案 0 :(得分:2)

至少对于Galaxy S4上的Kitkat 4.4.2,具有相对布局,我不得不在ImageView上调用invalidate(),我只是设置了ImageBitmap。如果我没有,我得到了空白屏幕。在setImageBitmap()之后添加invalidate()之后,我得到了图像。

答案 1 :(得分:2)

我遇到了同样的问题,并通过将视图的渲染更改为软件来解决它

<强> ImageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

答案 2 :(得分:1)

尝试有效加载位图:

public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    //BitmapFactory.Options optionss = new BitmapFactory.Options();
    //optionss.inPreferredConfig = Bitmap.Config.RGB_565;


    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    options.inPreferredConfig = Bitmap.Config.RGB_565;
    BitmapFactory.decodeFile(path,options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(path, options);
}
public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {

    final int halfHeight = height / 2;
    final int halfWidth = width / 2;

    // Calculate the largest inSampleSize value that is a power of 2 and keeps both
    // height and width larger than the requested height and width.
    while ((halfHeight / inSampleSize) > reqHeight
            && (halfWidth / inSampleSize) > reqWidth) {
        inSampleSize *= 2;
    }
}

return inSampleSize;}

答案 3 :(得分:0)

解决此问题的一种方法是在设置FileUri时,我使用Uri存储了SharedPreferences。所以在我的代码中:

public void takePhoto() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    fileUri = FileHelper.getOutputMediaFileUri();
    // Store uri to SharedPreferences
    pref.setImageUri(fileUri.toString());
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
    startActivityForResult(intent, TAKE_PICTURE);
}

在我的onActivityResult回调中:

if (requestCode == TAKE_PICTURE && resultCode == RESULT_OK) {
    // If user is taking photo then only call the SharedPreferences
    // If user is selecting photo from gallery, we can use the Intent data
    fileUri = Uri.parse(pref.getImageUri());
    if (fileUri.getPath().toString().length() < 1) {
        Toast.makeText(getApplicationContext(),
                "Sorry something went wrong ... Please try again",
                Toast.LENGTH_LONG).show();
    } else {
        String path = fileUri.getPath().toString();
        db_img_path = path;
        imageholder.setVisibility(View.VISIBLE);
        Bitmap bitmap = PathtoImage.previewImage(path);
        imagepreview.setImageBitmap(bitmap);
    }
}

奖金:)

在我的previewImage方法中,我对方向进行了调整,代码如下所示:

public static Bitmap previewImage(String path) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 4;
    final Bitmap bitmap = BitmapFactory.decodeFile(path, options);
    // Providing adjustment so that the image is shown in the correct orientation
    Matrix adjustment = adjustOrientation(path);
    Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
            bitmap.getWidth(), bitmap.getHeight(), adjustment, true);
    return resizedBitmap;
}

在这种方法中,我调用了另一种方法adjustOrientation,它为我提供了Matrix图像修复。

// Adjustment for orientation of images
public static Matrix adjustOrientation(String path) {
    Matrix matrix = new Matrix();
    try {
        ExifInterface exifReader = new ExifInterface(path);

        int orientation = exifReader.getAttributeInt(
                ExifInterface.TAG_ORIENTATION, -1);

        if (orientation == ExifInterface.ORIENTATION_NORMAL) {
            // do nothing
        } else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
            matrix.postRotate(90);
        } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
            matrix.postRotate(180);
        } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
            matrix.postRotate(270);
        }

    } catch (IOException e) {
        e.printStackTrace();
    }

    return matrix;
}

这是我对此问题的实施,如果有人对此有更好的实施,请发帖:)

答案 4 :(得分:0)

实际上它正在设置但是由于某种原因它不会出现。

profileImageView.post(new Runnable() {
                    @Override
                    public void run() {
                        profileImageView.setImageBitmap(bm);
                    }
                });

这适合我。

答案 5 :(得分:0)

就我而言,它是通过在 XML 中添加 android:layerType="software" 来修复的。

<ImageView
    android:id="@+id/imageView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layerType="software"
    android:src="@drawable/placeholder"/>

希望这也能帮到你!