我的Android照片应用无法显示相机中的图像,因为图像太大

时间:2015-09-21 11:32:44

标签: android image compression android-camera bitmapimage

好的,我希望我的应用能够让用户在应用内拍摄照片,以便以后可以查看照片。

问题是相机拍摄的照片很大,无法在应用程序中显示。

当尝试在应用程序中显示新照片时,这是写入logcat的错误类型:

Bitmap too large to be uploaded into a texture (5312x2988, max=4096x4096)

所以很明显我需要在将图像存储到设备上的 mynewapp 文件夹之前缩放/调整图像大小。

请参阅下面的代码,在我们尝试加载 mynewfile.jpg 之后,如果我们编辑文件源以引用500x500的图像文件,那么图像显示。但不会显示 mynewfile.jpg ,因为它太大了。

有人可以告诉我如何在将图像保存到设备之前调整图像大小吗?

非常感谢

这是我的代码:

显然我已经为 AndroidManifest.xml 文件添加了相应的权限

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

<uses-feature android:name="android.hardware.camera2" />

以下代码位于 TakePhotoDocActivity.java

    package com.example.frankjones.glovebox;

    import android.content.Intent;
    import android.graphics.drawable.Drawable;
    import android.net.Uri;
    import android.os.Bundle;
    import android.provider.MediaStore;
    import android.support.v7.app.AppCompatActivity;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.Toast;

    import java.io.File;

    public class TakePhotoDocActivity extends AppCompatActivity {

        // Set Camera Request
        static final int CAM_REQUEST = 1;

        // Prepare variables
        protected Button mTakePhotoBtn;
        protected ImageView mTakePhotoImg;

        // Start onCreate method
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_take_photo_doc);

            // Set variables
            mTakePhotoBtn = (Button) findViewById(R.id.takePhotoBtn);
            mTakePhotoImg = (ImageView) findViewById(R.id.takePhotoImg);

            // Listen to button
            mTakePhotoBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    File file = getFile();
                    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
                    startActivityForResult(cameraIntent, CAM_REQUEST);
                }
            }); // End listen to button

        } // End onCreate method

        private File getFile() {
            // Specify the directory we will store the file in
            File folder = new File("/storage/emulated/0/mynewapp/");

            // If the directory doesn't exist, create it
            if (!folder.exists()) {
                folder.mkdir();
            }

            // Specify the filename with its directory
            File imageFile = new File(folder, "mynewfile.jpg");

            // Return the filename
            return imageFile;
        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            // Display new photo in the ImageView
            mTakePhotoImg.setImageDrawable(Drawable.createFromPath("/storage/emulated/0/mynewapp/mynewfile.jpg"));

            // Toast a success message
            Toast.makeText(this, "Image saved!", Toast.LENGTH_LONG).show();
       }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.menu_take_photo_doc, menu);
            return true;
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();

            //noinspection SimplifiableIfStatement
            if (id == R.id.action_settings) {
                return true;
            }

            return super.onOptionsItemSelected(item);
        }
    }

最后,这是布局文件 activity_take_photo_doc.xml

    <LinearLayout 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:orientation="vertical"
        android:paddingBottom="16dp"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:paddingTop="16dp"
        tools:context="com.example.frankjones.glovebox.TakePhotoDocActivity">

        <Button
            android:id="@+id/takePhotoBtn"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="Take photo" />

        <ImageView
            android:id="@+id/takePhotoImg"
            android:layout_width="350dp"
            android:layout_height="300dp"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="20dp"
            android:src="@drawable/ic_glovebox_launcher_v2" />

    </LinearLayout>

任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:0)

  

有人可以告诉我如何在将图像保存到设备之前调整图像大小吗?

你不能。您根本没有保存图像。您调用的第三方相机应用程序正在保存图像。你没有写第三方相机应用程序。

您的主要选择是:

  1. 使用BitmapFactoryBitmapFactory.OptionsinSampleSize加载图片,因此占用的内存较少。

  2. 使用a third-party image-loading library为您处理选项#1。

  3. 使用第三方ImageView替代品,为您处理选项#1,作为其他功能的一部分(例如,缩放缩放),例如this library

  4. 另外:

    • 请不要硬编码路径。 /storage/emulated/0/对数亿人来说是错误的。始终使用框架提供的方法(主要在EnvironmentContext上)来获取感兴趣的根目录。

    • 请不要将用户自己的目录弄乱用户的外部存储空间。使用getExternalFilesDir()Context上的方法,以及Activity上的方法)可以访问外部存储上的框架提供的目录,该目录对于您的应用来说是唯一的。

答案 1 :(得分:0)

Android不能很好地处理大图像。我建议使用RapidDecoder下载(打开)和缩放。并SubsamplingScaleImageView显示它。