これは、デフォルトのカメラアプリケーションでは正常です。フルサイズの画像を取得する方法は、結果をファイルに入れるようにカメラアクティビティに指示することです。最初にファイルを作成してから、次のようにカメラアプリケーションを起動します。
outputFileName = createImageFile(".tmp");
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(outputFileName));
startActivityForResult(takePictureIntent, takePhotoActionCode);
次に、onActivityResultで、この画像ファイルを取得して操作できます。
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == takePhotoActionCode)
{
if (resultCode == RESULT_OK)
{
// NOTE: The intent returned might be NULL if the default camera app was used.
// This is because the image returned is in the file that was passed to the intent.
processPhoto(data);
}
}
}
processPhotoは次のようになります。
protected void processPhoto(Intent i)
{
int imageExifOrientation = 0;
// Samsung Galaxy Note 2 and S III doesn't return the image in the correct orientation, therefore rotate it based on the data held in the exif.
try
{
ExifInterface exif;
exif = new ExifInterface(outputFileName.getAbsolutePath());
imageExifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
}
catch (IOException e1)
{
e1.printStackTrace();
}
int rotationAmount = 0;
if (imageExifOrientation == ExifInterface.ORIENTATION_ROTATE_270)
{
// Need to do some rotating here...
rotationAmount = 270;
}
if (imageExifOrientation == ExifInterface.ORIENTATION_ROTATE_90)
{
// Need to do some rotating here...
rotationAmount = 90;
}
if (imageExifOrientation == ExifInterface.ORIENTATION_ROTATE_180)
{
// Need to do some rotating here...
rotationAmount = 180;
}
int targetW = 240;
int targetH = 320;
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(outputFileName.getAbsolutePath(), bmOptions);
int photoWidth = bmOptions.outWidth;
int photoHeight = bmOptions.outHeight;
int scaleFactor = Math.min(photoWidth/targetW, photoHeight/targetH);
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap scaledDownBitmap = BitmapFactory.decodeFile(outputFileName.getAbsolutePath(), bmOptions);
if (rotationAmount != 0)
{
Matrix mat = new Matrix();
mat.postRotate(rotationAmount);
scaledDownBitmap = Bitmap.createBitmap(scaledDownBitmap, 0, 0, scaledDownBitmap.getWidth(), scaledDownBitmap.getHeight(), mat, true);
}
ImageView iv2 = (ImageView) findViewById(R.id.photoImageView);
iv2.setImageBitmap(scaledDownBitmap);
FileOutputStream outFileStream = null;
try
{
mLastTakenImageAsJPEGFile = createImageFile(".jpg");
outFileStream = new FileOutputStream(mLastTakenImageAsJPEGFile);
scaledDownBitmap.compress(Bitmap.CompressFormat.JPEG, 75, outFileStream);
}
catch (Exception e)
{
e.printStackTrace();
}
}
注意すべき点の1つは、Nexusデバイスでは、呼び出しアクティビティは通常は破棄されないということです。ただし、Samsung Galaxy SIIIおよびNote2デバイスでは、通話アクティビティは破棄されます。したがって、outputFileNameをメンバー変数としてActivityに格納するだけで、アクティビティが終了したときに保存することを忘れない限り、カメラアプリが戻ったときにnullになります。とにかくそうするのは良い習慣ですが、これは私が以前に犯した間違いなので、私はそれについて言及したいと思いました。
編集:
あなたのコメントに関して、createImageFileは標準APIにありません、それは私が書いたものです(または私が借りたかもしれません:-)、私は覚えていません)、ここにcreateImageFile()のメソッドがあります:
private File createImageFile(String fileExtensionToUse) throws IOException
{
File storageDir = new File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES
),
"MyImages"
);
if(!storageDir.exists())
{
if (!storageDir.mkdir())
{
Log.d(TAG,"was not able to create it");
}
}
if (!storageDir.isDirectory())
{
Log.d(TAG,"Don't think there is a dir there.");
}
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "FOO_" + timeStamp + "_image";
File image = File.createTempFile(
imageFileName,
fileExtensionToUse,
storageDir
);
return image;
}