Imageview上的Android大图像在OOM错误时崩溃应用程序

问题描述 投票:0回答:2

以下代码允许用户从图库中选择4张图像,然后上传到服务器。目前,它正在上传所有4张小图片,但是当我尝试大图片时,它会因OOM错误而崩溃。

即使我尝试加载2张大图像,当我因OOM错误加载大图像时,应用程序也会崩溃。处理此类问题的最有效方法是什么?我已经阅读了此Android Bitmaps,但似乎无法在我的四个图像代码中实现。我已经尝试过毕加索,但该应用程序的行为仍然与上面相同(同上)。

SelectImageGallery1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Image1 From Gallery"), 1);

    }
});

SelectImageGallery2.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Image4 From Gallery"), 2);
    }
});

SelectImageGallery3.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Image3 From Gallery"), 3);

    }
});

SelectImageGallery4.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Image4 From Gallery"), 4);

    }
});

UploadImageServer.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        GetImageNameEditText1 = imageName1.getText().toString();
        GetImageNameEditText2 = imageName2.getText().toString();
        GetImageNameEditText3 = imageName3.getText().toString();
        GetImageNameEditText4 = imageName4.getText().toString();
        ImageUploadToServerFunction();
    }
});

}

public String getStringImage1(Bitmap bitmap1) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap1.compress(Bitmap.CompressFormat.JPEG, 60, baos);
    byte[] imageBytes = baos.toByteArray();
    String encodedImage1 = Base64.encodeToString(imageBytes, Base64.DEFAULT);
    return encodedImage1;
}

public String getStringImage2(Bitmap bitmap2) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap2.compress(Bitmap.CompressFormat.JPEG, 60, baos);
    byte[] imageBytes = baos.toByteArray();
    String encodedImage2 = Base64.encodeToString(imageBytes, Base64.DEFAULT);
    return encodedImage2;
}
public String getStringImage3(Bitmap bitmap3) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap3.compress(Bitmap.CompressFormat.JPEG, 60, baos);
    byte[] imageBytes = baos.toByteArray();
    String encodedImage3 = Base64.encodeToString(imageBytes, Base64.DEFAULT);
    return encodedImage3;
}

public String getStringImage4(Bitmap bitmap4) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap4.compress(Bitmap.CompressFormat.JPEG, 60, baos);
    byte[] imageBytes = baos.toByteArray();
    String encodedImage4 = Base64.encodeToString(imageBytes, Base64.DEFAULT);
    return encodedImage4;
}

@Override
protected void onActivityResult(int RC, int RQC, Intent I) {
    super.onActivityResult(RC, RQC, I);
    if (RC == 1 && RQC == RESULT_OK && I != null && I.getData() != null) {
        Uri uri = I.getData();
        try {
            bitmap1 = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
            imageView1.setImageBitmap(bitmap1);
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

    if (RC == 2 && RQC == RESULT_OK && I != null && I.getData() != null) {
        Uri uri = I.getData();
        try {
            bitmap2 = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
            //bitmap1 = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
            imageView2.setImageBitmap(bitmap2);
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

    if (RC == 3 && RQC == RESULT_OK && I != null && I.getData() != null) {
        Uri uri = I.getData();
        byte[] imageAsBytes = null;
        try {
            bitmap3 = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
            //bitmap1 = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
            imageView3.setImageBitmap(bitmap3);
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
    if (RC == 4 && RQC == RESULT_OK && I != null && I.getData() != null) {
        Uri uri = I.getData();
        try {
            bitmap4 = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
            //bitmap1 = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
            imageView4.setImageBitmap(bitmap4);
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}

public void ImageUploadToServerFunction() {
    final String imageName1 = GetImageNameEditText1.trim();
    final String imageName2 = GetImageNameEditText2.trim();
    final String imageName3 = GetImageNameEditText3.trim();
    final String imageName4 = GetImageNameEditText4.trim();
    final String imageView1 = getStringImage1(bitmap1);
    final String imageView2 = getStringImage2(bitmap2);
    final String imageView3 = getStringImage3(bitmap3);
    final String imageView4 = getStringImage4(bitmap4);
}
java android
2个回答
0
投票

ByteArrayOutputStream将所有数据保存在内存中。因此,您不能存储大于堆的数据。用第一种方法修改“清单”。

AndroidManifest.xml

<application
    android:largeHeap="true">
</application>

使用FileInputStream代替ByteArrayOutputStream。


0
投票

您应该解码位图以减小位图的大小,然后再上传到服务器:

fun decodeBitmapFromFile(imageFile: File, reqWidth: Int, reqHeight: Int): Bitmap {
    val options = BitmapFactory.Options()
    options.inJustDecodeBounds = true
    BitmapFactory.decodeFile(imageFile.absolutePath, options)

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false
    var scaledBitmap = BitmapFactory.decodeFile(imageFile.absolutePath, options)

    scaledBitmap = modifyOrientation(scaledBitmap, imageFile.absolutePath)
    return scaledBitmap
}

用途:

decodeBitmapFromFile(yourFile, 512, 512)

您可以随时更改大小(reqWidth \ reqHeight)您可以参考我的Github获取完整的代码:https://github.com/vancuong0429/ResizeImageUtil/blob/master/ResizeImageUtil

要从onActivityResult()获取文件,您可以参考链接

Android Studio get File from Gallery Intent

在onActivityResult()中:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (RC == 1 && RQC == RESULT_OK && I != null && I.getData() != null) {
        Uri uri = I.getData();
        // Creating file
        // Get the path from the Uri
        final String path = getPathFromURI(uri);
        if (path != null) {
            File yourFile = new File(path);
           bitmap1 = decodeBitmapFromFile(yourFile, 512, 512)
        }

    }
}
  • getPathFromURI

    public String getPathFromURI(Uri contentUri) {
    String res = null;
    String[] proj = {MediaStore.Images.Media.DATA};
    Cursor cursor = getContentResolver().query(contentUri, proj, null, null, null);
    if (cursor.moveToFirst()) {
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        res = cursor.getString(column_index);
    }
    cursor.close();
    return res;
    }
    
© www.soinside.com 2019 - 2024. All rights reserved.