【问题标题】:My Android photo app will not display images from the camera because the images are too large我的 Android 照片应用程序不会显示来自相机的图像,因为图像太大
【发布时间】:2015-09-21 11:32:44
【问题描述】:

好的,我希望我的应用能够让用户拍照并让他们稍后在应用内查看照片。

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

这是尝试在应用中显示新照片时写入 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>

任何帮助表示赞赏!

【问题讨论】:

标签: android image compression android-camera bitmapimage


【解决方案1】:

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

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

您的主要选择是:

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

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

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

还有:

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

  • 请不要将用户的外部存储与您自己的目录混淆。使用getExternalFilesDir()Context 上的一个方法,因此它在Activity 上可用)获取框架提供的外部存储上的目录,该目录对于您的应用来说是唯一的。

【讨论】:

  • 感谢您对此的意见。您能否根据我发布的代码向我发送一些示例代码?我已经玩 BitmapFactory 好几天了,却无处可去……
  • @Camdenmoo:“你能根据我发布的代码给我一些示例代码吗?” -- Stack Overflow 不是咨询服务。 “我已经玩 BitmapFactory 好几天了,却一无所获”——这个示例应用程序演示了使用 BitmapFactoryinSampleSize 从资产中加载一对图像,展示了下采样在内存方面的效果使用情况和产生的图像质量:github.com/commonsguy/cw-omnibus/tree/master/Bitmaps/…
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多