Pen, clutches, Bags, belt, Dress. Just say we have a beautiful body. At the end of the day it is a bit of luck and a lot of probability. Introduce yourself. When he answers, ask him to defend his choice. Do make online dating a priority. Wear comfortable clothes that you would always wear. Instead, just be yourself, nerves and all. Are you really ready for a loving relationship? Part some of your hair to your left side of your hair, curl the side that is not parted and hairspray all of your hair. Heart pendant: Girls love heart pendants online dating sites so give a pendant to her. You'd never behave this way in person, so don't do it online. Start looking. Don't be an idiot and don't just say stupid things in front of them that put someone else down or something nobody likes that. If he doesn't take you seriously your feelings will be hurt. By attending these sorts of events, making yourself available and approaching others, you'll be sure to build your confidence and make some new connections, she explains. Define the woman of your dreams. Keep reading for some tips. Don't say anything offensive! Progress slowly as you do not want to mess up things or make it tough for your ex-lover. Just take off then throw it away. Here are some suggestions to help you. It can also cause to them to distrust your sincerity, which will dampen any chances they'll fancy you. If he's looking at you, don't be afraid to make the first move and approach him with your number in a napkin and then walk away. After a few months together, you can surprise him with high heels and that cute black dress ;). Making you appear needy, or vulnerable. Do be on time. Don't just sit there. A blazer comes off as professional and therefore less playful, she explains. Send her jokes about things you know will make her laugh. If you obsess about the little things (this guy shares my passion for both dim sum and Noah Baumbach flicks!) you are likely to pass over the profiles of people who might actually make you happy. Men are so visual, they don't read your entire profile.

How to crop large photos with Android MediaStore

How to crop large photos with Android MediaStore

Overview

I'm writing this article to publish my brief research on the MediaStore crop functionality. Basically, if you want to write an application that leverages the existing Media Gallery and allows a user to pick (with optional face recognition) a portion of his/her image for use inside your application. There is an intent to do this, some bugs associated with it, and an overall lack of documentation on how to do it. Also, this article is based on 2.1 and tested on a Nexus One. The implementation of the Nexus One appears to be written by these guys (according to their site), seeĀ Media Gallery for Nexus One.

Feedback

This article is based on my research, needed for an application I wrote. If you find improvements over my suggested implementation, please let me know. I'll update this post accordingly.

Intent Details:

First, lets discuss this Intent, and its features. After seeing some example code, I found that I could call it easily using an Intent like this:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType(“image/*”);
intent.putExtra(“crop”, “true”);

However, this is when I lacked additional documentation, what are the options, etc… So, I have put together a table, and a demo program, in an attempt to demonstrated all available options from this control. You may use my example code in your application, and expand upon it. I'll attach it to this post.

Exta Options Table for image/* crop:

SetExtra DataType Description
crop String Signals the crop feature
aspectX int Aspect Ratio
aspectY int Aspect Ratio
outputX int width of output created from this Intent
outputY int width of output created from this Intent
scale boolean should it scale
return-data boolean Return the bitmap with Action=inline-data by using the data
data Parcelable Bitmap to process, you may provide it a bitmap (not tested)
circleCrop String if this string is not null, it will provide some circular cr
MediaStore.EXTRA_OUTPUT ("output") URI Set this URi to a File:///, see example code

Now, the biggest confusion is going to be around this MediaStore.EXTRA_OUTPUT and return-data options.

You basically have 2 ways to get the bitmap back from this Intent, you can ask for it inline or provide a Uri that it can write to.

Option #1: If you set return-data to "true", you will get back an Action = inline-data, and the bitmap returned will be inside the (Bitmap)extras.getParcelable("data"). Note: If the image ends up being to large, you will get a nasty exception with this method, so you are restricted to keeping your outputX and outputY small. In my code example attached, I did NOT use that method because of this reason.

Here is the code from CropImage.java (Android source code) where they write it inline:


// Return the cropped image directly or save it to the specified URI.
Bundle myExtras = getIntent().getExtras();
if (myExtras != null && (myExtras.getParcelable("data") != null
|| myExtras.getBoolean("return-data")))
{
Bundle extras = new Bundle();
extras.putParcelable("data", croppedImage);
setResult(RESULT_OK,(new Intent()).setAction("inline-data").putExtras(extras));
finish();

Option #2: If you set return-data to "false", you will not receive a Bitmap back from the onActivityResult Intent in-line, instead you will need to set MediaStore.EXTRA_OUTPUT to a Uri (of File scheme only) where you want the Bitmap to be stored. This has some restrictions, first you need to have a temp filesystem location in order to give the file scheme URI, not a huge problem (except on some devices that don't have sdcards).

Here is the code from CropImage.java (Android source code) where they write it to your Uri:


if (mSaveUri != null) {
OutputStream outputStream = null;
try {
outputStream = mContentResolver.openOutputStream(mSaveUri);
if (outputStream != null) {
croppedImage.compress(mOutputFormat, 75, outputStream);
}
} catch (IOException ex) {
// TODO: report error to caller
Log.e(TAG, "Cannot open file: " + mSaveUri, ex);
} finally {
Util.closeSilently(outputStream);
}
Bundle extras = new Bundle();
setResult(RESULT_OK, new Intent(mSaveUri.toString())
.putExtras(extras));
}

Example Code

I have attached some example code that should allow you to test various configurations. Let me know if you find it useful (or not).D
Download here ->MediaStoreTest

From the code (the essential parts)


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
thiz = this;
setContentView(R.layout.main);
mBtn = (Button) findViewById(R.id.btnLaunch);
photo = (ImageView) findViewById(R.id.imgPhoto);

mBtn.setOnClickListener(new OnClickListener(){

public void onClick(View v) {
try {
// Launch picker to choose photo for selected contact
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", aspectX);
intent.putExtra("aspectY", aspectY);
intent.putExtra("outputX", outputX);
intent.putExtra("outputY", outputY);
intent.putExtra("scale", scale);
intent.putExtra("return-data", return_data);
intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection",!faceDetection); // lol, negative boolean noFaceDetection
if (circleCrop) {
intent.putExtra("circleCrop", true);
}

startActivityForResult(intent, PHOTO_PICKED);
} catch (ActivityNotFoundException e) {
Toast.makeText(thiz, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
}
}
});

}

private Uri getTempUri() {
return Uri.fromFile(getTempFile());
}

private File getTempFile() {
if (isSDCARDMounted()) {

File f = new File(Environment.getExternalStorageDirectory(),TEMP_PHOTO_FILE);
try {
f.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
Toast.makeText(thiz, R.string.fileIOIssue, Toast.LENGTH_LONG).show();
}
return f;
} else {
return null;
}
}

private boolean isSDCARDMounted(){
String status = Environment.getExternalStorageState();

if (status.equals(Environment.MEDIA_MOUNTED))
return true;
return false;
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

switch (requestCode) {
case PHOTO_PICKED:
if (resultCode == RESULT_OK) {
if (data == null) {
Log.w(TAG, "Null data, but RESULT_OK, from image picker!");
Toast t = Toast.makeText(this, R.string.no_photo_picked,
Toast.LENGTH_SHORT);
t.show();
return;
}

final Bundle extras = data.getExtras();
if (extras != null) {
File tempFile = getTempFile();
// new logic to get the photo from a URI
if (data.getAction() != null) {
processPhotoUpdate(tempFile);
}
}
}
break;
}

}

zp8497586rq

Tags: , , , ,

10 Responses to “How to crop large photos with Android MediaStore”

  1. Ravindra kumar says:

    Hi,
    This is really a good example of cropping of an selected iamge.
    But my requirement is that i have already selected image and then i have to perform the cropping on the image.Can you please guide me how to do this taks.

  2. Philip says:

    This was amazingly helpful. I knew there were different options for this intent, but could not find a good description. With the Galaxy S phones having problems returning data from the gallery the temp file option is a great solution. The only thing it was missing was using the Parcelable Data to provide a bitmap to the crop function… if in fact this is actually possible. I would love to have that ability, but have not gotten it to work yet.

    I appreciate you work and research into this. It was very useful to me and very well presented!

  3. magic says:

    You save my life

  4. Jay says:

    I am sure going to try this. I hate to limit my app to 2.1+, but I will to get this to work. Thank you.! -UnConn

  5. markelov says:

    Great work. Where did you get those options for “image/*” from? I haven’t found any official documentation on the subject.

  6. Stevesy says:

    This project is awseome and has saved me lots of time!!! One question how does the circle crop work? I have an instance where this could be very beneficial.

    Thanks!

  7. Jitendra says:

    This is nice demo for croping image. But how does the circle crop work. I want to know.
    Please reply.
    thanks

  8. Thanks, great explanation, but unfortunately the demo code doesn’t seem to work for me.

    It always returns a null intent but RESULT_OK. I’ve debugged and the getTempUri seems to return a valid URI. I also tried disconnecting it from the PC, in case the SD card was busy or something.

    Any ideas what could be going wrong?
    Thanks!

  9. dv says:

    Hi,
    Thanks a lot. The post was really helpful.

    There is small remark. The code above has problem with newest android.Gallery3D. This gallery never returns action. I.e.data.getAction() is null always, even if gallery returns image successfully. So, I would suggest to comment part of the code:

    //if (data.getAction() != null) {
    processPhotoUpdate(tempFile);
    //}

    BTW: sometime, image could be selected not from a file, but from other source. It’s more common way to use URI instead of filename. See:
    http://stackoverflow.com/questions/5944282/retrieve-picasa-image-for-upload-from-gallery

    and sources of Android Bery library (class GetImageResult):
    http://code.google.com/p/android-beryl/source/browse/beryl-intents/src/org/beryl/intents/android/Gallery.java?r=e02c30d60aa22b2037ea18b7e6dab74ae4342555

  10. krishna kanth says:

    This was really very very very helpful. I have learnt almost all operations in CROP from this post. But i have one issue while passing MediaStore.EXTRA_OUTPUT parameter. It is saving the cropped image in with the file name that i have passed as URI. But the image was corrupted. I mean i can’t able to open the image. What is the mistake that i have done ????? PLease correct me.