android - 位图太大,无法在纹理中上传(模拟器和实际设备之间的差异)

标签 android bitmap

我创建了这个演示,它从图库中检索图像并将其显示在 ImageView 中(在对图像本身重新采样之后)https://github.com/svappdroid/BitmapDemo

在 Galaxy Nexus 上,我无法打开尺寸为 4307x2894 的图像,logcat 显示“位图太大,无法在纹理中上传”;奇怪的是,模拟 Galaxy Nexus 我能够打开相同的图像;为什么会出现这种行为以及如何在实际设备上解决它?

Activity 代码为:


    package com.example.bitmapdemo;

    import java.io.FileNotFoundException;

    import android.app.Activity;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.net.Uri;
    import android.os.Bundle;
    import android.util.DisplayMetrics;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.Toast;

    public class MainActivity extends Activity {
        public ImageView canvasImageView;
        public Button selectImageButton;
        public LinearLayout ll;
        public Bitmap image;

        //REQUEST CODE
        public static final int SELECT_IMAGE_REQ_CODE = 1;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ll = (LinearLayout) this.findViewById(R.id.LinearLayout1);
            canvasImageView = (ImageView) this.findViewById(R.id.canvasImageView);
            selectImageButton = (Button) this.findViewById(R.id.selectImageButton);

            selectImageButton.setOnClickListener(new OnClickListener(){

                @Override
                public void onClick(View v)
                {
                    Intent selectImageIntent = new Intent(Intent.ACTION_GET_CONTENT);
                    selectImageIntent.setType("image/*");
                    startActivityForResult(selectImageIntent, SELECT_IMAGE_REQ_CODE);
                }
            });
        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if(requestCode == SELECT_IMAGE_REQ_CODE)
            {
                switch(resultCode)
                {
                    case(RESULT_OK):
                        Uri imageUri = data.getData();

                        try
                        {
                            int inSampleSize = calculateInSampleSize(imageUri);
                            image = resampleImage(imageUri, inSampleSize);
                            canvasImageView.setImageBitmap(image);

                        }
                        catch(FileNotFoundException e){}
                }
            }
        }

        public int calculateInSampleSize(Uri imageUri) throws FileNotFoundException
        {
            BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri), null, opts);
            int imageWidth = opts.outWidth;
            int imageHeight = opts.outHeight;
            int inSampleSize = 4;

            //Get display dimension in order to calculate image ratio
            DisplayMetrics displayMetrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

            int reqWidth = displayMetrics.widthPixels;
            int reqHeight = displayMetrics.heightPixels;

            if(imageHeight > reqHeight || imageWidth > reqWidth)
            {
                final int heightRatio = Math.round((float)imageHeight / (float) reqHeight);
                final int widthRatio = Math.round((float) imageWidth / (float) reqWidth);

                inSampleSize = heightRatio 
<p>And here is the xml code for the layout: </p><pre><code><p></p> </code><pre><code><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <ImageView android:id="@+id/canvasImageView" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" android:layout_gravity="center" android:src="@drawable/ic_launcher" /> <Button android:id="@+id/selectImageButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/select_image_button" /> </LinearLayout> </code></pre> <p></p></pre>

最佳答案

您需要调整位图的大小以显示在 View 上。

Bitmap b = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
profileImage.setImageBitmap(Bitmap.createScaledBitmap(sourceBitmap, width, height, false));

在 adnroid 中处理位图有一个很好的文档。请引用:http://developer.android.com/training/displaying-bitmaps/index.html

在 SO 上你也可以找到一些解释。请参阅下文,这将有所帮助:https://stackoverflow.com/a/10703256/2035885 https://stackoverflow.com/a/4837803/2035885

关于android - 位图太大,无法在纹理中上传(模拟器和实际设备之间的差异),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19607658/

相关文章:

android - GradientDrawable绘制不同颜色的setColor方法

android - 基于软件的卡仿真 (HCE) 如何保证 NFC 安全?

android - 设置 Google Pay 以向用户汇款

java - java中有没有指针功能可以传递字节数组?

delphi - 从 TOleContainer 中提取位图?

android - 在 Activity 中的任意位置键入以在 android 中打开 edittext View

android - 从 ArrayList 释放位图的有效方法

windows - HDC 是否使用 alpha channel ?

java - 安卓 Java : bitmap resize define height and width auto

android - 在 Android 应用程序中更改位图分辨率