Android:从文件中旋转并显示图像

时间:2014-09-01 02:07:13

标签: java android android-bitmap

我有一个非常简单的布局与ImageView。我的应用程序打开相机,保存图像,然后使用BitmapFactory.decodeFile在ImageView中显示图像。唯一的问题是它被轮换了。我理解a)这是由于手机的相机默认为横向,所以这需要在代码中处理,b)图像处理必须在与UI不同的线程中完成。

Android培训文档似乎适用于从资源ID而不是文件路径加载图像。这只会让事情变得棘手,因为我能够按照教程进行操作,但最终难以协调差异。

我当然是新手,所以如果有人能够给我一个高层次的概述,为了实现这一目标需要做些什么,我真的很感激。以下代码是我目前将位图添加到ImageView的地方。我假设我对单独线程的调用将进入onCreate

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

    Bitmap bm = BitmapFactory.decodeFile(MainActivity.image_path);

    displayImageView = (ImageView) findViewById(R.id.myImageView);

    displayImageView.setImageBitmap(bm);
}

4 个答案:

答案 0 :(得分:6)

使用ExifInterface进行旋转

picturePath = getIntent().getStringExtra("path");
Bitmap bitmap = BitmapFactory.decodeFile(picturePath);
ExifInterface exif = new ExifInterface(picturePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);

Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
    matrix.postRotate(90);
    break;
case ExifInterface.ORIENTATION_ROTATE_180:
    matrix.postRotate(180);
    break;
case ExifInterface.ORIENTATION_ROTATE_270:
    matrix.postRotate(270);
    break;
default:
    break;
}

myImageView.setImageBitmap(bitmap);
bitmap.recycle();

注意:此处picturePath已从Gallery

中选择了图片的路径

答案 1 :(得分:2)

我能够使用以下方法。我认为你可以在没有AsyncTask的情况下做到这一点,但似乎最佳实践表明你应该在非UI线程中执行图像处理(请随意纠正 - 我对此很新)。

可以对此进行改进的是以更精细的方式处理扩展。 inSampleSize是一个很棒的工具,但它只能按2的幂进行扩展。另一个改进是最初只将meta / EXIF数据读入bmOriginal,因为此变量的唯一用途是检索高度和宽度。

ImageView XML - 非常标准。 android:layout_width / height设置为fill_parent

来自活动的java文件 -

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

    new ImageRotator().execute(MainActivity.image_path);
}

private class ImageRotator extends AsyncTask<String, Void, Bitmap>{
    protected Bitmap doInBackground(String... image_path){

        BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
        bitmapOptions.inSampleSize = 4;
        Bitmap bmOriginal = BitmapFactory.decodeFile(image_path[0], bitmapOptions);

        Matrix matrix = new Matrix();

        matrix.postRotate(90);

        bmOriginal = Bitmap.createBitmap(bmOriginal, 0, 0, bmOriginal.getWidth(), bmOriginal.getHeight(), matrix, true);

        return bmOriginal;
    }

    protected void onPostExecute(Bitmap result) {
        myImageView = (ImageView) findViewById(R.id.myImageView);

        myImageView.setImageBitmap(result);
    }
}

找到了缩放过程here,并对AsyncTask的功能here进行了很好的解释。

非常感谢所有回复的人 - 请随时告诉我这是否偏离基础,或者即使有更好的方法可以做到这一点。

答案 2 :(得分:0)

为什么要费心旋转图像。如你所说&#34; ImageView本身是正确定向的。只是它内部的图像始终以逆时针方向显示90度。 &#34;然后就是 使ImageView顺时针旋转90度,图像将正确显示。

    displayImageView.setRotation(90);

答案 3 :(得分:0)

您可以使用矩阵旋转图像或在xml中设置旋转。但是,如果您想要更多控制,可以查看为旋转图像而保存到磁盘的本教程:

How to rotate an image in android

我希望有所帮助。