gpt4 book ai didi

java - 从我的自定义图库 android 中选择图像时出错

转载 作者:行者123 更新时间:2023-12-01 09:55:23 24 4
gpt4 key购买 nike

如果我选择一些图像,它会起作用,但是当我选择其他尺寸可能更大的图像时,它会给我这个错误:

java.lang.OutOfMemoryError: Failed to allocate a 79629324 byte allocation with 16777120 free bytes and 46MB until OOM

我有这样的类(class):

我点击进入自定义图库 Activity 的主要 Activity :

public class gallerygridselect extends BaseNavegationActivity implements View.OnClickListener{

private LinearLayout lnrImages;
private Button btnAddPhots,btnSaveImages;
private ArrayList<String> imagesPathList;
private Bitmap yourbitmap;
private final int PICK_IMAGE_MULTIPLE = 1;
ArrayList<String> a = new ArrayList<String>();
long imageSize = 0; // kb
ImageView imageView;
private String[] imagesPath;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.gallery_picker);
lnrImages = (LinearLayout) findViewById(R.id.lnrImages);
btnAddPhots = (Button) findViewById(R.id.btnAddPhots);
btnSaveImages = (Button) findViewById(R.id.btnSaveImages);
btnAddPhots.setOnClickListener(this);
btnSaveImages.setOnClickListener(this);

}


@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnAddPhots:
Intent intent = new Intent(gallerygridselect.this, gallerygrid.class);
startActivityForResult(intent, PICK_IMAGE_MULTIPLE);
break;
case R.id.btnSaveImages:
if (imagesPathList != null) {
if (imagesPathList.size() > 0) {
Toast.makeText(gallerygridselect.this, imagesPathList.size() + " fotos selecionadas", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(gallerygridselect.this, imagesPathList.size() + " fotos selecionadas", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(gallerygridselect.this, "Selecione as fotos", Toast.LENGTH_SHORT).show();
}
break;
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == PICK_IMAGE_MULTIPLE) {
imagesPathList = new ArrayList<String>();
imagesPath = data.getStringExtra("data").split("\\|");

for (int i = 0; i < imagesPath.length; i++) {
System.out.println("imagesPath "+imagesPath[i]);
}

imageSize = this.getFileSize(String.valueOf(imagesPath));

Log.d("PATH", "" + imagesPath);
try {
lnrImages.removeAllViews();
} catch (Throwable e) {
e.printStackTrace();
}
for (int i = 0; i < imagesPath.length; i++) {
imagesPathList.add(imagesPath[i]);
Log.e("Pathlist", "" + imagesPathList);
yourbitmap = BitmapFactory.decodeFile(imagesPath[i]);
Log.i("BITMAP", "" + yourbitmap);

imageView = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(5, 5, 5, 5);
imageView.setLayoutParams(params);

imageView.setImageBitmap(BitmapHelper.decodeFile(imagesPath[i], 320, 480, true));
imageView.setAdjustViewBounds(true);
lnrImages.addView(imageView);
}
}
}
}

private long getFileSize(String imagesPath) {
long length = 0;
try {
File file = new File(imagesPath);
length = file.length();
length = length / 1024;
} catch (Exception e) {
e.printStackTrace();
}
return length;
}

private String getPath(Uri uri) {
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}

我的位图帮助类:

public class BitmapHelper {
//decodes image and scales it to reduce memory consumption
public static Bitmap decodeFile(String bitmapFile, int requiredWidth, int requiredHeight, boolean quickAndDirty)
{
try
{
//Decode image size
BitmapFactory.Options bitmapSizeOptions = new BitmapFactory.Options();
bitmapSizeOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null, bitmapSizeOptions);

// load image using inSampleSize adapted to required image size
BitmapFactory.Options bitmapDecodeOptions = new BitmapFactory.Options();
bitmapDecodeOptions.inTempStorage = new byte[16 * 1024];
bitmapDecodeOptions.inSampleSize = computeInSampleSize(bitmapSizeOptions, requiredWidth, requiredHeight, false);
bitmapDecodeOptions.inPurgeable = true;
bitmapDecodeOptions.inDither = !quickAndDirty;
bitmapDecodeOptions.inPreferredConfig = quickAndDirty ? Bitmap.Config.RGB_565 : Bitmap.Config.ARGB_8888;

Bitmap decodedBitmap = BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null, bitmapDecodeOptions);

// scale bitmap to mathc required size (and keep aspect ratio)

float srcWidth = (float) bitmapDecodeOptions.outWidth;
float srcHeight = (float) bitmapDecodeOptions.outHeight;

float dstWidth = (float) requiredWidth;
float dstHeight = (float) requiredHeight;

float srcAspectRatio = srcWidth / srcHeight;
float dstAspectRatio = dstWidth / dstHeight;

// recycleDecodedBitmap is used to know if we must recycle intermediary 'decodedBitmap'
// (DO NOT recycle it right away: wait for end of bitmap manipulation process to avoid
// java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@416ee7d8
// I do not excatly understand why, but this way it's OK

boolean recycleDecodedBitmap = false;

Bitmap scaledBitmap = decodedBitmap;
if (srcAspectRatio < dstAspectRatio)
{
scaledBitmap = getScaledBitmap(decodedBitmap, (int) dstWidth, (int) (srcHeight * (dstWidth / srcWidth)));
// will recycle recycleDecodedBitmap
recycleDecodedBitmap = true;
}
else if (srcAspectRatio > dstAspectRatio)
{
scaledBitmap = getScaledBitmap(decodedBitmap, (int) (srcWidth * (dstHeight / srcHeight)), (int) dstHeight);
recycleDecodedBitmap = true;
}

// crop image to match required image size

int scaledBitmapWidth = scaledBitmap.getWidth();
int scaledBitmapHeight = scaledBitmap.getHeight();

Bitmap croppedBitmap = scaledBitmap;

if (scaledBitmapWidth > requiredWidth)
{
int xOffset = (scaledBitmapWidth - requiredWidth) / 2;
croppedBitmap = Bitmap.createBitmap(scaledBitmap, xOffset, 0, requiredWidth, requiredHeight);
scaledBitmap.recycle();
}
else if (scaledBitmapHeight > requiredHeight)
{
int yOffset = (scaledBitmapHeight - requiredHeight) / 2;
croppedBitmap = Bitmap.createBitmap(scaledBitmap, 0, yOffset, requiredWidth, requiredHeight);
scaledBitmap.recycle();
}

if (recycleDecodedBitmap)
{
decodedBitmap.recycle();
}
decodedBitmap = null;

scaledBitmap = null;
return croppedBitmap;
}
catch (Exception ex)
{
ex.printStackTrace();
}
return null;
}

/**
* compute powerOf2 or exact scale to be used as {@link BitmapFactory.Options#inSampleSize} value (for subSampling)
*
// @param requiredWidth
// @param requiredHeight
* @param powerOf2
* weither we want a power of 2 sclae or not
* @return
*/
public static int computeInSampleSize(BitmapFactory.Options options, int dstWidth, int dstHeight, boolean powerOf2)
{
int inSampleSize = 1;

// Raw height and width of image
final int srcHeight = options.outHeight;
final int srcWidth = options.outWidth;

if (powerOf2)
{
//Find the correct scale value. It should be the power of 2.

int tmpWidth = srcWidth, tmpHeight = srcHeight;
while (true)
{
if (tmpWidth / 2 < dstWidth || tmpHeight / 2 < dstHeight)
break;
tmpWidth /= 2;
tmpHeight /= 2;
inSampleSize *= 2;
}
}
else
{
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) srcHeight / (float) dstHeight);
final int widthRatio = Math.round((float) srcWidth / (float) dstWidth);

// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}

return inSampleSize;
}

public static Bitmap drawableToBitmap(Drawable drawable)
{
if (drawable instanceof BitmapDrawable)
{
return ((BitmapDrawable) drawable).getBitmap();
}

Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);

return bitmap;
}

public static Bitmap getScaledBitmap(Bitmap bitmap, int newWidth, int newHeight)
{
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;

// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);

// RECREATE THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
}

我是 Android 开发新手,我能做些什么来解决这个问题。提前致谢。

最佳答案

您需要传递具有高度和宽度的文件路径。所以它会返回小图像:-

Bitmap ShrinkBitmap(String file, int width, int height){

BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);

int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);

if (heightRatio > 1 || widthRatio > 1)
{
if (heightRatio > widthRatio)
{
bmpFactoryOptions.inSampleSize = heightRatio;
} else {
bmpFactoryOptions.inSampleSize = widthRatio;
}
}

bmpFactoryOptions.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
return bitmap;
}

有关更多信息,请参阅链接:-

http://voidcanvas.com/whatsapp-like-image-compression-in-android/

关于java - 从我的自定义图库 android 中选择图像时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37282390/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com