ข้อผิดพลาดการดูภาพ Android ไม่เพียงพอในหน่วยความจำ

ในโปรเจ็กต์ Android ของฉัน ฉันมี imageButton และหลังจากคลิกแล้ว มันจะต้องเปิด Activity ใหม่ด้วย imageView และใน Activity ใหม่ของฉัน ฉันต้องเห็นรูปภาพของ ImageButton ในรูปแบบขนาดใหญ่เท่านั้น ขนาดรูปภาพของฉันคือ 17mb และฉันก็มีหน่วยความจำไม่เพียงพอ ข้อผิดพลาด. แต่โค้ดของฉันใช้ได้กับรูปภาพที่มีขนาดน้อย ใครสามารถช่วยปรับขนาดภาพหรือเปลี่ยนตัวเลือกบิตแมปหรือคำแนะนำอื่นได้บ้าง ฉันใหม่ใน Android และขออภัยสำหรับภาษาอังกฤษที่ไม่ดี :)

นี่คือ XML ของกิจกรรมใหม่ของฉัน

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:id="@+id/LL11"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content">
<TextView
 android:id="@+id/textView1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Here must be an image">
</TextView>

<ImageView
    android:id="@+id/imageView1"
    android:maxWidth="10px"
    android:maxHeight="10px"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:src="@drawable/ic_action_search" />

</LinearLayout>

และโค้ดจาวา

package com.example.example;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.ImageView;

package com.example.example;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.ImageView;

public class ActivityTwo extends Activity {


    @Override
      protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.custom_dialog);
        Bundle extras = getIntent().getExtras();
        String path = extras.getString("path");
        if(null != path) 
        {
            Uri myUri = Uri.parse(path);
            super.onCreate(savedInstanceState);
            ImageView img1 = (ImageView) findViewById(R.id.imageView1);
           img1.setImageURI(myUri);

        }
    }
}

person Hayk Nahapetyan    schedule 03.09.2012    source แหล่งที่มา
comment
stackoverflow.com/a/7400814/792232 ตรวจสอบสิ่งนี้   -  person Abhi    schedule 03.09.2012
comment
ถ้าฉันเขียนอะไรแบบนี้ Bitmap btm = etImageToImageView(myUri.toString()); img1.setImageBitmap(btm); มันต้องได้ผลเหรอ? หรือฉันกำลังทำอะไรผิด? และขอบคุณมาก :)   -  person Hayk Nahapetyan    schedule 03.09.2012
comment
ส่งเส้นทางรูปภาพไปยังวิธีการของฉันที่นั่นในลิงก์   -  person Abhi    schedule 03.09.2012


คำตอบ (5)


ในรหัสของคุณเริ่มต้นที่ if(null != path) เปลี่ยนเป็นสิ่งนี้

int size = 10; //minimize  as much as you want
if(path != null){
     Bitmap bitmapOriginal = BitmapFactory.decodeFile(pathath);
     Bitmap bitmapsimplesize = Bitmap.createScaledBitmap(bitmapOriginal,bitmapOriginal.getWidth() / size, bitmapOriginal.getHeight() / size, true);
     bitmapOriginal.recycle();
     img1.setImageBitmap(bitmapsimplesize);

}
person Community    schedule 03.09.2012
comment
เราจะให้เส้นทางได้อย่างไรหากต้องการปรับขนาดภาพที่วาดได้ - person swati; 27.09.2012
comment
สิ่งนี้ใช้ได้กับฉันก่อนอื่นคุณจะได้บิตแมปดั้งเดิมจากนั้นคุณสามารถปรับขนาดได้ - person ; 15.05.2013
comment
บิตแมป bitmapOriginal = BitmapFactory.decodeFile(pathath); โหลดรูปภาพในหน่วยความจำแล้ว ดังนั้นฉันไม่คิดว่ามันจะช่วยได้ แต่จะแย่กว่านั้น - person taotao; 02.06.2015

ฉันมีปัญหากับข้อยกเว้น Images และ OutOfMemory และปัญหาทั้งหมดมีสาเหตุมาจากการที่ฉันใช้หน่วยความจำมากเกินไปที่กำหนดให้กับแอป (เรียกว่าฮีป)

เช่นเดียวกับที่ฉันเห็นในโค้ดของคุณ คุณสร้างรูปภาพทุกครั้งที่กดปุ่ม และอย่างที่คุณพูด หากรูปภาพมีขนาด 17M อาจเป็นไปได้ว่าอุปกรณ์ของคุณมีคุณภาพต่ำ ก็จะมี 20M ของฮีปสูงสุดสำหรับแต่ละแอป ดังนั้นคุณจึงไม่มีหน่วยความจำเหลืออยู่สองภาพ

บางทีคุณอาจสร้างรูปภาพได้เพียงครั้งเดียว หากคุณต้องสร้างรูปภาพมากกว่าหนึ่งรูป ลองลบรูปภาพก่อนหน้าออก และลองโทร System.gc() อาจมีประโยชน์

หากคุณต้องการสร้างภาพมากกว่าหนึ่งภาพ มากกว่าหนึ่งภาพ คุณสามารถสร้างภาพขนาดย่อได้โดยตั้งค่าตัวเลือก inSampleSize ก่อนที่จะสร้างภาพ หากคุณใส่ค่า 2 ให้กับแอตทริบิวต์นี้ คุณจะได้รูปภาพต้นฉบับ 1/2 ที่มีคุณภาพและขนาดลดลง

บางสิ่งเช่นนี้:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2; // Or other value that you estimate

จากนั้นสร้างภาพด้วยตัวเลือกเหล่านี้

ป.ล.: ไม่จำเป็นต้องโทร super.onCreate() มากกว่าหนึ่งครั้ง

person Victor de Francisco Domingo    schedule 03.09.2012
comment
ฉันลองแบบนี้แล้ว แต่บอกความจริงว่ามันใช้งานไม่ได้ แต่ตอนนี้หลังจากคำตอบของคุณ ฉันเข้าใจอย่างลึกซึ้ง ฉันจะลองอีกครั้ง :) ขอบคุณมาก - person Hayk Nahapetyan; 03.09.2012

โค้ดด้านล่างสามารถช่วยคุณปรับขนาดรูปภาพได้

File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
                File output = new File(dir, "image.png");


    path = output.getAbsolutePath();
    Bitmap b =  BitmapFactory.decodeFile(cPath);
    Bitmap out = Bitmap.createScaledBitmap(b, 320, 480, false);
    FileOutputStream fout;
    try{
        fout = new FileOutputStream(output);
        out.compress(Bitmap.CompressFormat.PNG, 100, fout);
        fout.flush();
        fout.close();
        b.recycle();
        out.recycle();
    }catch(Exception e){
        e.printStackTrace();
    }
person Hardik Nadiyapara    schedule 03.09.2012

ฉันรู้ว่านี่เป็นกระทู้เก่า แต่เนื่องจากฉันเพิ่งพบข้อผิดพลาดนี้ในวันนี้และพบว่าฉันได้รับข้อผิดพลาดเดียวกัน แต่ด้วยเหตุผลอื่น ฉันจึงต้องการโพสต์มุมมองที่แตกต่างออกไปในเรื่องนี้

ในกรณีของฉัน นี่เป็นปัญหาขนาดที่ใหญ่เกินไป และไม่ใช่ขนาด (200K) เมื่อปรับขนาดให้เล็กลง (640px x 480px) ปัญหาก็ได้รับการแก้ไข

หวังว่านี่จะช่วยคนอื่นในอนาคตที่เจอโพสต์นี้

person Azadi B.    schedule 01.03.2015

วิธีแก้ปัญหาข้างต้นใช้ไม่ได้ในกรณีของฉัน ดังนั้นฉันจึงพบว่าวิธีนี้ใช้ได้ผลสำหรับฉัน ลองวิธีนี้ดู

private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException {
    BitmapFactory.Options op = new BitmapFactory.Options();
    op.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(
            getActivity().getContentResolver().openInputStream(selectedImage), null, op);

    final int REQUIRED_SIZE = 1000;

    int width_tmp = op.outWidth, height_tmp = op.outHeight;
    int scale = 1;
    while (true) {
        if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) {
            break;
        }
        width_tmp /= 2;
        height_tmp /= 2;
        scale *= 2;
    }

    BitmapFactory.Options op2 = new BitmapFactory.Options();
    op2.inSampleSize = scale;
    return BitmapFactory.decodeStream(
            getActivity().getContentResolver().openInputStream(selectedImage), null, op2);
}

จากนั้นตั้งค่าส่งคืน Bitmap กลับไปเป็น imageView ของคุณเหมือนด้านล่าง

yourImageView.setImageBitmap(returnedBitmap);
person Dulanga    schedule 03.07.2019