我正在制作一个应用程序,它可以初始化相机,然后在拍摄照片后,可以导入照片,用户可以进一步在上面绘图。
编码:
A 类:
public OnClickListener cameraButtonListener = new OnClickListener()
{
@Override
public void onClick(View v)
{
vibrate();
Toast.makeText(Doodlz.this, R.string.message_initalize_camera, Toast.LENGTH_SHORT).show();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
};
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK)
{
Bitmap photo = (Bitmap) data.getExtras().get("data");
Bitmap photocopy = photo.copy(Bitmap.Config.ARGB_8888, true);
doodleView.get_camera_pic(photocopy);
}
}
涂鸦 View :
public void get_camera_pic (Bitmap photocopy)
{
// get screen dimension first
WindowManager wm = (WindowManager) context_new.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
final int screenWidth = display.getWidth();
final int screenHeight = display.getHeight();
bitmap = photocopy;
bitmap = Bitmap.createScaledBitmap(bitmap, screenWidth, screenHeight, true);
bitmapCanvas = new Canvas(bitmap);
invalidate(); // refresh the screen
}
问题:
可以使用相机成功捕获照片并返回给用户的doodleView
。但是由于导入的图片尺寸很小,只有缩略图大小!! (不知道为什么),所以我厌倦了放大它,然后分辨率很差。
我的问题是,如何修改上面的代码,以便将拍摄的照片尺寸设置为适合屏幕尺寸,并将返回的照片设置为屏幕的 1:1,而不是像缩略图一样? (最好适合 1:1 的屏幕,因为如果它是以原始照片尺寸导入,则照片尺寸会大于屏幕,然后需要按比例缩小并按不同的宽度和高度比例进行扭曲以适合完整屏幕)
谢谢!!
最佳答案
这对于默认相机应用程序来说是正常的。获取全尺寸图像的方法是告诉相机 Activity 将结果放入文件中。首先创建一个文件,然后启动相机应用程序,如下所示:
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();
}
}
需要注意的是,在 Nexus 设备上,调用 Activity 通常不会被销毁。然而,在 Samsung Galaxy S III 和 Note 2 设备上,调用 Activity 被破坏了。因此,仅将 outputFileName 作为成员变量存储在 Activity 中将导致它在相机应用程序返回时为空,除非您记得在 Activity 结束时保存它。无论如何,这样做是个好习惯,但这是我以前犯过的错误,所以我想我应该提一下。
编辑:
关于您的评论,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;
}
关于来自相机的 android 位图只是缩略图大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14788070/