我一直处理Android上的图片,已经有好几天了,我似乎无法解决它。
在我的应用中有一个"添加照片"按钮。当用户点击它时,她可以从图库中选择一张照片,或者用相机拍摄一张新照片。
但是为了避免出现OutOfMemoryError,我必须降低分辨率,以至于发送到服务器的图片几乎只是一个缩略图。
当我将200更改为250时,在此行上会出现上述错误! 位图缩放= Bitmap.createScaledBitmap(bitmap2,200,200,true);
(错误发生在Android 4.2+上,而不是在较低的Androids上。它在Android 4.1上完全正常,即使有400,400)
我的代码中哪一部分错了?
以下是代码:
public class CreatePropertyActivity5 extends ActionBarActivity {
protected static final int SELECT_PICTURE = 1;
private static final int ACTIVITY_REQUEST_CODE_IMAGE = 100;
private static final int IMAGE_DESCRIPTION = 200;
LinearLayout ll;
private List<File> cameraImageFiles;
private JSONRequestForCreatePropertyListing propertyListing;
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_property_5);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
propertyListing = (JSONRequestForCreatePropertyListing) getIntent().getSerializableExtra("JSONRequestForCreatePropertyListing");
CreatePropertListingAsync cplp = new CreatePropertListingAsync(this, propertyListing);
cplp.execute();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.create_property_activity5, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void onClickTakePicture(View v) throws IOException {
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
cameraImageFiles = new ArrayList<File>();
int i=0;
for(ResolveInfo res : listCam) {
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.MEDIA_IGNORE_FILENAME, ".nomedia");
//** below 4 lines put the uri of the camera taken picture to the EXTRA_OUTPUT
File cameraImageOutputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "myFileName");
cameraImageFiles.add(cameraImageOutputFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraImageFiles.get(i)));
i++;
cameraIntents.add(intent);
}
// Filesystem.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "add new");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
startActivityForResult(chooserIntent, ACTIVITY_REQUEST_CODE_IMAGE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent)
{
ll = (LinearLayout) findViewById(R.id.llCreatePropertyImages);
switch(requestCode) {
// For sending photos to server. We come here from activity51
case IMAGE_DESCRIPTION:
String s = imageReturnedIntent.getStringExtra("key");
//user entered description is in "key"
imageView.setTag(s);
Bitmap bitmap1 = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
ByteArrayOutputStream stream=new ByteArrayOutputStream();
bitmap1.compress(Bitmap.CompressFormat.PNG, 90, stream);
byte[] image=stream.toByteArray();
String img_str = Base64.encodeToString(image, 0);
//This part sends the picture to the server
ArrayList<Photos> photos = new ArrayList<Photos>();
photos.add(new Photos(new Ax(img_str)));
int id = Integer.parseInt((String) ((TextView) findViewById(R.id.txt_property_listing_ID)).getText());
int editPass = Integer.parseInt((String) ((TextView) findViewById(R.id.txt_property_listing_password)).getText());
JSONRequestForAddPhoto jr = new JSONRequestForAddPhoto(id, editPass, photos);
new AddPhotoAsync(this, jr).execute();
break;
//For choosing photos from gallery or taking one with camera
case ACTIVITY_REQUEST_CODE_IMAGE:
if(resultCode == RESULT_OK){
Uri uri = null;
if(imageReturnedIntent == null){ //since we used EXTRA_OUTPUT for camera, so it will be null
for(int i=0;i<cameraImageFiles.size();i++){
if(cameraImageFiles.get(i).exists()){
uri = Uri.fromFile(cameraImageFiles.get(i));
break;
}
}
}
else { // from gallery
uri = imageReturnedIntent.getData();
}
if(uri != null){
imageView = new ImageView(this);
imageView.setPadding(0, 10, 0, 0);
ll.setVisibility(View.VISIBLE);
try {
Bitmap bitmap2 = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
Bitmap scaled = Bitmap.createScaledBitmap(bitmap2, 250, 250, true);
bitmap2.recycle();
imageView.setImageBitmap(scaled);
ll.addView(imageView);
//*** show activity51
Intent i= new Intent(this, CreatePropertyActivity51.class);
i.putExtra("photo", scaled);
startActivityForResult(i,IMAGE_DESCRIPTION);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
答案 0 :(得分:0)
我认为您的代码没有错,但可以进行优化。但如果你处理一些大图像,我建议你看一下这个答案:https://stackoverflow.com/a/27270469/2101822
答案 1 :(得分:0)
我查看了您的代码,但您没有采用开发人员网站中提到的方式 如何load large bitmaps efficiently:
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
先试试吧!