在我的应用程序中,我必须将所选图像上传到parse.com以进行打印输出。 我必须保持图像质量,我无法调整图像大小。 我必须在parse.com上传图片..我不需要在设备屏幕上显示它们(图像是表格图库或来自facebook专辑......或来自SD卡)。我不能按照要求缩小它们。
我在BitmapFactory.decodeFile()上遇到OutOfMemory错误。如何解决这个错误?
正在使用android:largeHeap =" true"可以解决我的问题吗?
我在三星SM-G900T上遇到了这次崩溃,但不是在模拟器上......
我试图把
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inPreferredConfig = Config.RGB_565;
但它不起作用。 下面是我的AsyncTask类,用于将图像上传到Parse.com
class UploadFileFromURL extends AsyncTask<String, String, String> {
ProgressDialog dialog;
String albumId = "";
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... f_url) {
try {
for (int i = 0; i < arrListImgBean.size(); i++) {
if (!isUploading || objAsyncUpload.isCancelled()) {
break;
}
try {
if (arrListImgBean.get(i).imageStatus == 1)
continue;
else if (arrListImgBean.get(i).imageStatus == 2) {
isPhotodeleted = true;
publishProgress("" + countUploaded);
deletePhoto(i);
}
else {
isPhotodeleted = false;
try {
Bitmap b = null;
InputStream is = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inPreferredConfig = Config.RGB_565; // to
// reduce
// the
// memory
options.inDither = true;
if (arrListImgBean.get(i).imgURL
.startsWith("http")) {
try {
URL url = new URL(
arrListImgBean.get(i).imgURL);
is = url.openConnection()
.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
b = BitmapFactory.decodeStream(is, null,
options);
} else {
b = BitmapFactory.decodeFile(
arrListImgBean.get(i).imgURL,
options);
}
// Convert it to byte
ByteArrayOutputStream stream = new ByteArrayOutputStream();
// Bitmap out = Bitmap.createScaledBitmap(b,
// 1500, 2100, false);
b.compress(Bitmap.CompressFormat.PNG, 100,
stream);
byte[] image = stream.toByteArray();
ParseFile file = new ParseFile("Android.png",
image);
file.save();
String uploadedUrl = file.getUrl();
if (uploadedUrl != null) {
ParseObject imgupload = new ParseObject(
"Photo");
imgupload.put("userName", ParseUser
.getCurrentUser().getEmail());
imgupload.put("photoURL", file);
imgupload.put("photoID",
arrListImgBean.get(i).imageId);
imgupload.put("count", 1);
imgupload.put("albumName", albumId);
imgupload.save();
String objId = imgupload.getObjectId();
if (objId != null && !objId.isEmpty()) {
countUploaded++;
publishProgress("" + countUploaded);
database.updateImageStatus(
arrListImgBean.get(i).imageId,
Constants.STATUS_UPLOADED,
objId, uploadedUrl);
}
}
} catch (Exception e) {
}
}
} catch (Exception e) {
isUploading = false;
e.printStackTrace();
}
}
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
@Override
protected void onPostExecute(String file_url) {
// dismissDialog(progress_bar_type);
isUploading = false;
btnUploadImages.setBackgroundResource(R.drawable.upload_photo);
vprogress.setCompoundDrawables(null, null, null, null);
// stopLoading();
setProgressMsg();
}
}
答案 0 :(得分:0)
android:largeHeap="true"
这行代码可以解决您的问题,但它是一个临时解决方案,但如果图像数量或图像大小增加,可能会再次发生崩溃。最好使用Picasso库来处理图像
答案 1 :(得分:0)
考虑你有一个1024x1024dp的图像和一个512x512dp的设备(这两个图只是为了理解)。因此,在这种情况下,在较小规模的设备上加载全分辨率图像会浪费内存。您可以做的是缩小图像,使其适合设备屏幕。通过这种方式,您不仅可以节省大量内存,还可以获得清晰,清晰的图像。
我正在添加用于缩放我目前在项目中使用的图像的代码。
final FileInputStream streamIn = new FileInputStream(file);
final BitmapFactory.Options ops = new BitmapFactory.Options();
ops.inJustDecodeBounds = true;
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 300;
int width_tmp = ops.outWidth, height_tmp = ops.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;
}
ops.inJustDecodeBounds = false;
ops.inSampleSize = scale;
bitmap = BitmapFactory.decodeStream(streamIn, null, ops); //This gets the image
streamIn.close();
根据设备的屏幕显示大小选择REQUIRED_SIZE
值。
答案 2 :(得分:0)
try {
image = readInFile(path);
}
catch(Exception e) {
e.printStackTrace();
}
// Create the ParseFile
ParseFile file = new ParseFile("picturePath", image);
// Upload the image into Parse Cloud
file.saveInBackground();
// Create a New Class called "ImageUpload" in Parse
ParseObject imgupload = new ParseObject("Image");
// Create a column named "ImageName" and set the string
imgupload.put("Image", "picturePath");
// Create a column named "ImageFile" and insert the image
imgupload.put("ImageFile", file);
// Create the class and the columns
imgupload.saveInBackground();
// Show a simple toast message
Toast.makeText(LoadImg.this, "Image Saved, Upload another one ",Toast.LENGTH_SHORT).show();
private byte[] readInFile(String path) throws IOException {
// TODO Auto-generated method stub
byte[] data = null;
File file = new File(path);
InputStream input_stream = new BufferedInputStream(new FileInputStream(
file));
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
data = new byte[16384]; // 16K
int bytes_read;
while ((bytes_read = input_stream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, bytes_read);
}
input_stream.close();
return buffer.toByteArray();
}