jam*_*z77 0 png android bitmapimage image-quality
我在尝试使用 Android 应用程序将照片保存到存储时遇到问题。该应用程序使用设备相机拍摄照片并将其以 PNG 格式保存到设备。
由于某种原因,无论我做什么或将图像存储在哪里,质量都很差。该应用程序是一个相当大的现有项目,因此我想知道将图像保存到设备时是否需要考虑其他因素,或者可能是另一种覆盖质量的方法。
这是以前的开发人员编写的函数:
public String saveImageToDevice(Bitmap image) {
saveCanvasImage(image);
String root = Environment.getExternalStorageDirectory().toString()+"/Android/data/com.app.android";
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fname = "Image-"+ timeStamp +".png";
File file = new File (myDir, fname);
if (file.exists ()){
file.delete ();
}
try {
Toast.makeText(getActivity(), "Saving Image...", Toast.LENGTH_SHORT).show();
Log.i("Image saved", root+"/saved_images/"+fname);
FileOutputStream out = new FileOutputStream(file);
image.compress(CompressFormat.PNG, 100, out);
imageLocations.add(fname);
out.flush();
out.close();
//return myDir.getAbsolutePath() + "/" +fname;
return fname;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我自己从网上的例子中尝试过的一个功能:
public void saveCanvasImage(Bitmap b) {
File f = new File(Environment.getExternalStorageDirectory().toString() + "/img.png");
try {
f.createNewFile(); // your mistake was at here
FileOutputStream fos = new FileOutputStream(f);
b.compress(CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
}catch (IOException e){
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
这两种方法都会产生同样非常差的图像。我在下面发布了前后片段。这就是相机预览的样子。

这是保存后的结果图像。

在与一些人交谈后,我添加了我的相机意图代码:
public void startCameraIntent(){
/*************************** Camera Intent Start ************************/
// Define the file-name to save photo taken by Camera activity
String fileName = "Camera_Example.png";
// Create parameters for Intent with filename
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fileName);
values.put(MediaStore.Images.Media.DESCRIPTION,"Image capture by camera");
// imageUri is the current activity attribute, define and save it for later usage
@SuppressWarnings("unused")
Uri imageUri = getActivity().getContentResolver().insert( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
/**** EXTERNAL_CONTENT_URI : style URI for the "primary" external storage volume. ****/
// Standard Intent action that can be sent to have the camera
// application capture an image and return it.
Intent intent = new Intent( MediaStore.ACTION_IMAGE_CAPTURE );
//intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); // set the image file name
startActivityForResult( intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
/*************************** Camera Intent End ************************/
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,EXTRA_OUTPUT 行已被注释掉,因为它会导致崩溃并出现以下错误:
12-17 13:31:37.339: E/AndroidRuntime(16123): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65537, result=-1, data=null} to activity {}: java.lang.NullPointerException
Run Code Online (Sandbox Code Playgroud)
我还包含了我的 onActivityresult 代码:
public void onActivityResult( int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
int page = mViewPager.getCurrentItem();
NotesPagerFragment note = pages.get(page);
Log.i("Request Code", ""+requestCode);
//For the ImageCapture Activity
if ( requestCode == 1) {
if ( resultCode != 0) {
/*********** Load Captured Image And Data Start ****************/
Bitmap bp = (Bitmap) data.getExtras().get("data");
//add the image to the note through a function call
note.addImage(bp);
note.saveImageToDevice(bp);
//String imageId = convertImageUriToFile( imageUri,CameraActivity);
// Create and excecute AsyncTask to load capture image
// new LoadImagesFromSDCard().execute(""+imageId);
/*********** Load Captured Image And Data End ****************/
} else if ( resultCode == 0) {
Toast.makeText(this.getActivity(), " Picture was not taken ", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this.getActivity(), " Picture was not taken ", Toast.LENGTH_SHORT).show();
}
}
//For the deleting an Image
if (requestCode == 2) {
String location = (String) data.getExtras().get("imageLocation");
if(data.getExtras().get("back") != null){
//just going back, don't mind me
}else {
//Toast.makeText(this.getActivity(), "BOO", Toast.LENGTH_SHORT).show();
note.removeNoteImageFromView(location);
database.removeSingleNoteImageFromSystemByLocation(location);
}
}
}
Run Code Online (Sandbox Code Playgroud)
好的,在Melquiades的大力帮助下,我最终解决了这个问题。我遇到的问题是我的意图和 onActivityResult 正在检索图像的缩略图并将其放大(因此质量很差)。
\n下面的代码行负责获取缩略图预览 (120px x 160px):
\nBitmap bp = (Bitmap) data.getExtras().get("data");\nRun Code Online (Sandbox Code Playgroud)\n为了访问完整图像,我需要将 EXTRA_OUTPUT 添加到意图中,如下所示:
\npublic void startCameraIntent(){\n /*************************** Camera Intent Start ************************/ \n File imageFile = new File(imageFilePath); \n Uri imageFileUri = Uri.fromFile(imageFile); // convert path to Uri\n \n // Standard Intent action that can be sent to have the camera\n // application capture an image and return it. \n Intent intent = new Intent( MediaStore.ACTION_IMAGE_CAPTURE );\n intent.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri); // set the image file name \n \n startActivityForResult( intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);\n \n \n /*************************** Camera Intent End ************************/\n}\nRun Code Online (Sandbox Code Playgroud)\n我还在活动顶部将 imageFilePath 声明为字符串:
\nString timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());\nString imageFilePath = Environment.getExternalStorageDirectory().toString()+"/Android/data/com.my.app/Image-"+timeStamp+".png";\nRun Code Online (Sandbox Code Playgroud)\n然后我必须更改 onActivityResult 以便它可以访问完整图像以使用:
\npublic void onActivityResult( int requestCode, int resultCode, Intent data){\n super.onActivityResult(requestCode, resultCode, data);\n \n int page = mViewPager.getCurrentItem();\n NotesPagerFragment note = pages.get(page);\n Log.i("Request Code", ""+requestCode);\n //For the ImageCapture Activity\n if ( requestCode == 1) {\n \n if ( resultCode != 0) {\n /*********** Load Captured Image And Data Start ****************/\n \n // Decode it for real \n BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();\n bmpFactoryOptions.inJustDecodeBounds = false; \n\n //imageFilePath image path which you pass with intent \n Bitmap bp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions); \n \n //rotate image by 90 degrees\n Matrix rotateMatrix = new Matrix();\n rotateMatrix.postRotate(90);\n Bitmap rotatedBitmap = Bitmap.createBitmap(bp, 0, 0, bp.getWidth(), bp.getHeight(), rotateMatrix, false);\n \n //add the image to the note through a function call\n note.addImage(rotatedBitmap);\n note.saveImageToDevice(rotatedBitmap);\n //String imageId = convertImageUriToFile( imageUri,CameraActivity); \n // Create and excecute AsyncTask to load capture image\n // new LoadImagesFromSDCard().execute(""+imageId); \n /*********** Load Captured Image And Data End ****************/ \n \n } else if ( resultCode == 0) {\n Toast.makeText(this.getActivity(), " Picture was not taken ", Toast.LENGTH_SHORT).show();\n } else {\n \n Toast.makeText(this.getActivity(), " Picture was not taken ", Toast.LENGTH_SHORT).show();\n }\n }\n \n //For the deleting an Image\n if (requestCode == 2) {\n String location = (String) data.getExtras().get("imageLocation");\n if(data.getExtras().get("back") != null){\n //just going back, don\'t mind me\n }else {\n //Toast.makeText(this.getActivity(), "BOO", Toast.LENGTH_SHORT).show();\n note.removeNoteImageFromView(location);\n database.removeSingleNoteImageFromSystemByLocation(location);\n \n }\n }\n }\nRun Code Online (Sandbox Code Playgroud)\n这里的关键部分是:
\n // Decode it for real \n BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();\n bmpFactoryOptions.inJustDecodeBounds = false; \n\n //imageFilePath image path which you pass with intent \n Bitmap bp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions); \nRun Code Online (Sandbox Code Playgroud)\n此代码将您在 imageFilePath 中保存的图像解码为可用的位图。从这里您可以正常使用它。
\n有时(显然这很常见)图像旋转了 90\xc2\xb0,如果您需要的话,下一段代码会将其旋转回来:
\n//rotate image by 90 degrees\nMatrix rotateMatrix = new Matrix();\nrotateMatrix.postRotate(90);\nBitmap rotatedBitmap = Bitmap.createBitmap(bp, 0, 0, bp.getWidth(), bp.getHeight(), rotateMatrix, false);\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
3979 次 |
| 最近记录: |