We have been using a bunch of code that uses the camera with the desired end result, but I want to get to the bottom of this with clean code. I'm simply following the Android docs here verbatim, and getting a rotated thumbnail. Below is the code, please find the working project in this branch of my Bitbucket repository.
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
ImageView view = (ImageView) findViewById(R.id.imageView);
view.setImageBitmap(imageBitmap);
}
}
I know that this is just the thumbnail. But it seems the thumbnail is completely useless, unless you get the full file and read the exif info from that.
I know that StackOverflow says "get the exif rotation from the full image file and rotate the actual bitmap before recompressing it into another jpg file". But isn't this a little too much unnecessary computation? What good is the thumbnail if it's useless by itself without getting the orientation from the full file?
Am I missing something?
Related
I know this is quite common to ask but I'm really confused this time. All I need is to save the BLOB image to the SQLite and I have already done and saved it to SQLite, actually, I have two images saved as BLOB in SQLite I compared them but I really don't know the difference the other one contains 3000X4000 pixels 2.72 MIB which much heavier size and the other one is much lighter which is 182x250 50.81Kib and this is what I really want the lightier size. I upload two images to see what's really happening
Actually, I've been trying to develop Text Image Recognition. The image which bigger size sample, after capturing an image it should be crop and saves to SQLite while the lesser size just directly captured image and save to SQLite now they have the save function to save to SQLite I really don't know why they have different size and I think the problem is on the crop or Pickcamera()method which it changes the size of the image? is that possible?.
The bigger one
The lesser one
The bigger size code Image after clicking button it goes to pickCamera() method and the image display to the another activity
public void pickCamera() {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "NewPic");
values.put(MediaStore.Images.Media.DESCRIPTION, "Image to Text");
image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values);
Intent cameraIntent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK){
if (requestCode == IMAGE_PICK_GALLER_CODE){
CropImage.activity(data.getData()).setGuidelines(CropImageView.Guidelines.ON).start(this);
}
if (requestCode == IMAGE_PICK_CAMERA_CODE){
CropImage.activity(image_uri).setGuidelines(CropImageView.Guidelines.ON).start(this);
}
}
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE){
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if(resultCode ==RESULT_OK){
Uri resultUri = result.getUri();
resultUri.getPath();
BitmapDrawable bitmapDrawable = (BitmapDrawable)mPreviewIv.getDrawable();
Bitmap bitmap = bitmapDrawable.getBitmap();
TextRecognizer recognizer = new TextRecognizer.Builder(getApplicationContext()).build();
if(!recognizer.isOperational()){
Toast.makeText(this,"Error",Toast.LENGTH_SHORT).show();
}
else{
Frame frame = new Frame.Builder().setBitmap(bitmap).build();
SparseArray<TextBlock> items = recognizer.detect(frame);
StringBuilder sb = new StringBuilder();
for (int i = 0; i<items.size(); i++){
TextBlock myItem = items.valueAt(i);
sb.append(myItem.getValue());
sb.append("\n");
}
Intent i = new Intent(ScanCashCard.this, ScannedDetails.class);
//camera I want to display the image view to another Activity and save to SQLite
i.putExtra("CashCardImage",image_uri.toString());
startActivity(i);
}
}
}
}
Display to another activity
String resultUri = extras.getString("CashCardImage");
Uri myUri = Uri.parse(resultUri);
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),myUri);
mPreviewCashCard.setImageBitmap(bitmap);
This code is from the lesser size
public void pickcamera(){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 101);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 101){
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
mPreview4PsId.setImageBitmap(bitmap);
}
}
I think the problem is on the pickCamera() method which they different but when I follow the code from the lesser size the crop will not be available anymore, I stuck with this module anyone can help me? this is really help me a lot
So I just add a bunch of code which set and replace the default resolution of the Image pixel because I guess the default Pixel of the Image resolution from camera is 3000x4000 pixel so you just need to set the width and height of the ImageView. So I just set 187x250
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),myUri);
mPreviewCashCard.setImageBitmap(Bitmap.createScaledBitmap(bitmap, 187, 250, false));
This question already has answers here:
Android Camera Intent: how to get full sized photo?
(8 answers)
Closed 5 years ago.
I am currently doing a fault reporting page whereby the end user is able to report an image either by capturing using the camera or selecting a photo from the gallery. I am not sure why but when the image is taken using the camera, the height and width returned is about 220 by 180 which is a very blur image. I have tried looking online for other tutorials but my code seems to be the same as the others. Not too sure if it is my phone or what.
My code for Camera Intent:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_CAMERA);
My code after Capturing image from Camera:
thumbnail = (Bitmap) data.getExtras().get("data");
bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
ivImage.setVisibility(View.VISIBLE);
ivImage.setImageBitmap(thumbnail);
I've tried getting the width and height before and after compression, both returns the same value.
May be you should not compress the image rather simply use BitmapFactory.decodeFile(filePath) or any suitable method for getting your image from file into a bitmap (if not done already) and then set the bitmap object to the ImageResource like this:
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
mImageView.setImageBitmap(bitmap);
And don't simply type cast the data received from intent. As far as I know about camera activity class, it will return a URI of the captured image. Try to receive it in onActivityResult() like this:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) return;
if (requestCode == REQUEST_CAMERA) {
Uri photoUri = data.getData();
// Calculate the bitmap here according to the width of the device
((ImageView) findViewById(R.id.captured_image)).setImageBitmap(bitmap);
}
super.onActivityResult(requestCode, resultCode, data);
}
I've written code in Android to capture an image and then use that image as follows:
private static Intent i;
final static int cons = 0;
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
public void takePicture()
{
i= new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //Open camera
startActivityForResult(i, cons);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Log.d("Testing if condition", "Test"); //This code does not execute
Bundle ext = data.getExtras();
Log.d("Upload image", ext.toString());
sendForUpload(data); // function to upload file to server
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
}
This code lets me take a photo and it saves to the SD card. However, I'm not sure if the file is sent to the sendForUpload function where I've handled getting the path and uploading the file. In fact nothing inside the if (resultCode == RESULT_OK) block works. How do I use the image captured from this activity?
Well, you have a few problems.
First, you are calling startActivityForResult(i, cons);. cons is 0. You are trying to compare 0 with CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE. Since CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE is 100, that will not work.
Second, you are calling data.getExtras().toString() (split over two Java statements). I would expect this to return a value like android.os.Bundle#34334143. If that is what you want to upload, fine. I am guessing that you want to upload the image. Since you did not include EXTRA_OUTPUT in your ACTION_IMAGE_CAPTURE Intent, you get a Bitmap of the thumbnail image taken by the camera via data.getParcelableExtra("data").
Third, you are making inappropriate assumptions:
This code lets me take a photo and it saves to the SD card.
There is no requirement for the camera app to save the image anywhere, let alone to removable storage. In fact, I would argue that this is a bug in your camera app. That is not surprising, as ACTION_IMAGE_CAPTURE implementations have bugs.
where I've handled getting the path and uploading the file
There is no path. You did not include EXTRA_OUTPUT in your ACTION_IMAGE_CAPTURE Intent, and so all you get back is the thumbnail Bitmap.
I'm using this to put the image in a ImageView:
Uri uri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
You can use bitmap or uri objects for upload or show your picture..
Hope it helps you.
I have a button in my code to take a picture:
<Button
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#drawable/cameralogo"
android:id="#+id/buttonCamera" />
When i click it it opens the camera and saves a picture, path is String mCurrentPhotoPath;
after the camera intent was displayed i want the button to show the image as background (android:background="mCurrent.....")???
how do do this?
Here is the solution.
You cannot set background only by path or URI, you'll need to create a Bitmap( and use ImageButton) or a Drawable out of it.
Using Bitmap and ImageButton:
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
yourImageButton.setImageBitmap(bitmap);
Using Drawable and Button:
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
Drawable d = new BitmapDrawable(getResources(),bitmap);
yourButton.setBackground(d);
Have you had a look at this question yet?
How to set the button background image through code
You cant do this in the xml but only programmatically. Just get a reference to the newly created picture like described here:
How to get path of a captured image in android
To start the camera intent:
...
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
activity.startActivityForResult(takePictureIntent, PHOTO_ACTIVITY_REQUEST_CODE);
...
Where PHOTO_ACTIVITY_REQUEST_CODE is just a integer constant unique within activity to be used as request codes while starting intent for results.
To Receive photo in the onActivityResult, and update background of the view
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PHOTO_ACTIVITY_REQUEST_CODE && data != null) {
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap photo = (Bitmap) extras.get("data");
if (photo != null) {
// mView should refer to view whose reference is obtained in onCreate() using findViewById(), and whose background you want to update
mView.setBackground(new BitmapDrawable(getResources(), photo));
}
}
}
The above code does not use full size photo. For that, you will have to ask Photo intent to save it to a file, and read the file. Details are presenthere
I'm following along on this example:
http://developer.android.com/training/camera/photobasics.html
If you Ctrl-F for this putExtra(MediaStore.EXTRA_OUTPUT it'll take you to a segment of code I'm unsure of. Further up in the app, they override onActivityResult and try to pull the image from this intent out of the activity result to display in the app, but when I was doing this the Intent arg in onActivityResult was null. I tried changing my putExtra to take "data" instead of MediaStore.EXTRA_OUTPUT and suddenly it works perfectly.
Can anyone explain what this tutorial is trying to get me to do?
So basically, the code in question:
static final int REQUEST_IMAGE_CAPTURE = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
...
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(imageBitmap);
}
}
Intent data in onActivityResult is null, so it'd crash when i called getExtras. I changed dispatchTakePictureIntent to putExtra("data", Uri.fromFile(photoFile)); and it works.
I'm just confused if this is a blunder on Google's part and made a mistake in their tutorial, or if I did something wrong / don't understand? Only reason I thought to make this change is because it uses the string data when it calls extras.get("data"). So I don't even understand my solution :(
putExtra("NameOfExtra", object)
so they are getting an extra named "data" - the string is the NAME of the extra value that was previously put.