I have managed to implement usage of the ACTION_IMAGE_CAPTURE intend in order to take a photo in my app. For some reason, when the photo is taken, the preview image (the image that is displayed with the tick/cross icon before it is sent back to my app) is square and really low resolution, even though the picture which I have managed to save to storage is not. I have been through all the questions that complain about a low quality image being returned, and all the answers give solutions on how to get the higher quality image in your app itself, not how to tell the camera app to use a full quality preview. Any help will be greatfully appreciated!
问题:
回答1:
not how to tell the camera app to use a full quality preview
That is because there is no way for you to tell the camera app "to use a full quality preview".
There thousands upon thousands of Android device models. There are hundreds of built-in camera apps across those device models, and many more available for download from places like the Play Store. The behavior of ACTION_IMAGE_CAPTURE
is up to those apps' developers, including:
whether or not they have a confirmation screen ("displayed with the tick/cross icon before it is sent back to my app")
what the image looks like on that confirmation screen
Other than EXTRA_OUTPUT
, there is no other documented aspect to the ACTION_IMAGE_CAPTURE
protocol in terms of input, and so camera apps do not need to offer anything else.
For whatever reason, your particular camera app is not implemented especially well.
回答2:
try to check below code work for my app perfect.
TakeImageActivity.java
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class TakeImageActivity extends ActivityBase implements OnClickListener {
File file,mFileTemp;
Button buttonTakeImageCam;
ImageView imageView;
Uri mPhotoUri;
Bitmap thumbnail;
private Uri fileUri;
private static final String IMAGE_DIRECTORY_NAME = "PhotoEditor Camera";
public static final int MEDIA_TYPE_IMAGE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.take_image_activity);
file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/FrameImages");
initializetion();
}
private void initializetion() {
// TODO Auto-generated method stub
buttonTakeImageCam = (Button) findViewById(R.id.buttonTakeImageCam);
buttonTakeImageCam.setOnClickListener(this);
if (!isDeviceSupportCamera()) {
Toast.makeText(getApplicationContext(),
"Sorry! Your device doesn't support camera",
Toast.LENGTH_LONG).show();
// will close the app if the device does't have camera
finish();
}
}
private boolean isDeviceSupportCamera() {
if (getApplicationContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
private static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
+ IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.buttonTakeImageCam:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, 2);
break;
default:
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (resultCode != RESULT_OK)
return;
switch (requestCode) {
case 2:
if (resultCode == RESULT_OK) {
// successfully captured the image
// display it in image view
previewCapturedImage();
} else if (resultCode == RESULT_CANCELED) {
// user cancelled Image capture
Toast.makeText(getApplicationContext(),
"User cancelled image capture", Toast.LENGTH_SHORT)
.show();
} else {
// failed to capture image
Toast.makeText(getApplicationContext(),
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
break;
}
}
private void previewCapturedImage() {
try {
// bimatp factory
BitmapFactory.Options options = new BitmapFactory.Options();
// downsizing image as it throws OutOfMemory Exception for larger
// images
options.inSampleSize = 2;
final Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(),
options);
//Set image here
imgPreview.setImageBitmap(bitmap);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
public Bitmap getPreview(String fileName) {
File image = new File(fileName);
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(image.getPath(), bounds);
if ((bounds.outWidth == -1) || (bounds.outHeight == -1)) {
return null;
}
int originalSize = (bounds.outHeight > bounds.outWidth) ? bounds.outHeight
: bounds.outWidth;
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = originalSize / 64;
// opts.inSampleSize = originalSize;
return BitmapFactory.decodeFile(image.getPath());
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}
take_image_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" >
<Button
android:id="@+id/buttonTakeImageCam"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:textSize="25sp"
android:text="Camera"/>
</RelativeLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.camera.photo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="9" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="true"/>
<application
android:icon="@drawable/ic_launcher"
android:largeHeap="true"
android:label="@string/app_name" >
<activity
android:name=".TakeImageActivity"
android:hardwareAccelerated="false"
android:screenOrientation="portrait"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>