【发布时间】:2015-10-16 12:59:03
【问题描述】:
在我的应用中,用户可以从相机或图库中添加许多图像。 有一个 addPhoto 按钮,用户单击它,她可以选择相机或画廊,选择或拍照,然后将照片添加到页面中。这可以一直持续下去。
除了一件事之外,每件事都运行良好: 有些图像是纵向的,我需要旋转它们(因为 Android 会旋转它们并使它们变成横向,我必须将它们旋转回来)。但是我不能用相机图片来做,因为它们的光标是空的。
图像保存在设备上。 Uri 不是。我还应该检查什么? 我究竟做错了什么?奇怪的是,当从图库中选择图像时,一切都完美无缺!
这是处理图像的 Activity 的代码:
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;
private static List<File> cameraImageFiles;
private static Bitmap selectedImageBitmap;
private static LinearLayout ll;
private static int id = 0;
private static int password = 0;
private static JSONRequestForCreatePropertyListing propertyListing;
private static ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_property_5);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//if not null, means Android has killed the process while the user has been working with camera or gallery to add images, and the onCreate is called AGAIN. And we don't want to initialize the layout again cause we will loose our previously added photos.
if (propertyListing==null) {
propertyListing = (JSONRequestForCreatePropertyListing) getIntent().getSerializableExtra("JSONRequestForCreatePropertyListing");
CreatePropertListingAsync cplp = new CreatePropertListingAsync(this, propertyListing);
cplp.execute();
ll = (LinearLayout) findViewById(R.id.llCreatePropertyImages);
}
else {
//If Android has killed the activity once and this is the second time we are in onCreate(), the static ll which has the previously added images in it won't be attached to the xml page and so we have to add it manually.
LinearLayout ll2 = (LinearLayout) findViewById(R.id.ll_activity_create_property);
((ViewGroup)ll.getParent()).removeView(ll);
ll2.addView(ll);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
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.jpg");
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)
{
switch(requestCode) {
// For sending photos to server. We come here from activity51 when user clicks on send photo. This "case" happens second.
case IMAGE_DESCRIPTION:
if(resultCode == RESULT_OK){
//add the image to the activity5 page.
imageView = new ImageView(this);
imageView.setPadding(0, 10, 0, 0);
ll.setVisibility(View.VISIBLE);
if (findViewById(R.id.ll_create_property_successful)!= null)
findViewById(R.id.ll_create_property_successful).setVisibility(View.VISIBLE);
imageView.setImageBitmap(selectedImageBitmap);
ll.addView(imageView);
if ((TextView) findViewById(R.id.txt_property_listing_code)!= null)
((TextView) findViewById(R.id.txt_property_listing_code)).setText(""+id);
if ((TextView)findViewById(R.id.txt_property_listing_password)!= null)
((TextView) findViewById(R.id.txt_property_listing_password)).setText(""+password);
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)));
//if not null, means Android has killed the process while the user has been working with camera or gallery to add images, and the onCreate is called AGAIN. And we don't want to initialize the layout again cause we will loose our previously added photos.
JSONRequestForAddPhoto jr = new JSONRequestForAddPhoto(id, password, photos);
new AddPhotoAsync(this, jr).execute();
}
//If user has pressed the cancel button and not the send photo button (in activity51) we come here and do nothing.
break;
//After the user has selected a photo (or taken one with camera) we come here :). This "case" happens first for a photo.
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
if (cameraImageFiles!=null && cameraImageFiles.get(0)!=null)
for(int i=0;i<cameraImageFiles.size();i++){
if(cameraImageFiles.get(i).exists()){
uri = Uri.fromFile(cameraImageFiles.get(i));
break;
}
}
else
Toast.makeText(this, "Sorry :( A problem occured whille trying to add this photo", Toast.LENGTH_LONG);
}
else { // from gallery
uri = imageReturnedIntent.getData();
}
if(uri != null){
try {
selectedImageBitmap = decodeSampledBitmapFromResource(uri, 500, 500);
Matrix matrix = new Matrix();
matrix.postRotate(getOrientation(this, uri));
selectedImageBitmap = Bitmap.createBitmap(selectedImageBitmap, 0, 0, selectedImageBitmap.getWidth(), selectedImageBitmap.getHeight(), matrix, true);
Intent i= new Intent(this, CreatePropertyActivity51.class);
i.putExtra("photoUri", uri);
startActivityForResult(i,IMAGE_DESCRIPTION);
//*** show activity51
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public Bitmap decodeSampledBitmapFromResource(Uri uri, int reqWidth, int reqHeight) throws IOException {
ContentResolver cr = getContentResolver();
InputStream inStream = cr.openInputStream(uri);
// First decode with inJustDecodeBounds=true to check dimensions
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(inStream, null, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
inStream.close();
inStream = cr.openInputStream(uri);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap result = BitmapFactory.decodeStream(inStream, null , options);
inStream.close();
return result;
}
public int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
int height = options.outHeight;
int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
int halfHeight = height / 2;
int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2.
while ((halfHeight / inSampleSize) > reqHeight || (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static int getOrientation(Context context, Uri photoUri) {
/* it's on the external media. */
Cursor cursor = context.getContentResolver().query(photoUri, new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
if (cursor == null)
return 0;
if (cursor.getCount() != 1) {
return -1;
}
cursor.moveToFirst();
return cursor.getInt(0);
}
}
【问题讨论】:
标签: android image camera android-cursor