Android: 将位图保存到外部存储器
Android: Saving Bitmap to External Memory
我目前正在从事一个项目,即捕获图像、裁剪图像、处理图像然后保存处理后的图像。我的问题在于保存处理后的图像。我无法保存处理后的图像。对于捕获的每张图像,捕获的图像将显示在图库中,而不是处理后的图像。我在想,因为捕获图像代码将图像保存到 SD 卡,我无法保存位图上的处理图像......我希望你能启发我我的代码有什么问题。顺便说下代码没有错误。
更具体一点,我正在使用的应用程序捕获图像然后裁剪图像。之后该图像将显示在 imageView 中。处理后,它将再次显示在 imageView 中。当我将图像保存在外部存储器中时,没有任何反应...
这是捕获和裁剪图像的代码
public class MainActivity extends Activity {
ImageView mainImageview;
Button mainButtonTakePhoto;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeControls();
}
private void initializeControls() {
mainImageview = (ImageView)findViewById(R.id.imageView1);
mainButtonTakePhoto = (Button)findViewById(R.id.button3);
mainButtonTakePhoto.setOnClickListener(new OnClickListener() {
@Override
public void onClick (View v) {
/* create an instance of intent
* pass action android.media.action.IMAGE_CAPTURE
* as argument to launch camera */
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
/*create instance of File with name img.jpg*/
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "img.jpg");
/*put uri as extra in intent object*/
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
/*start activity for result pass intent as argument and request code */
startActivityForResult(intent, 1);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//if request code is same we pass as argument in startActivityForResult
if(requestCode==1){
//create instance of File with same name we created before to get image from storage
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "img.jpg");
//Crop the captured image using an other intent
try {
/*the user's device may not support cropping*/
cropCapturedImage(Uri.fromFile(file));
}
catch(ActivityNotFoundException aNFE){
//display an error message if user device doesn't support
String errorMessage = "Sorry - your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
if(requestCode==2){
//Create an instance of bundle and get the returned data
Bundle extras = data.getExtras();
//get the cropped bitmap from extras
Bitmap thePic = extras.getParcelable("data");
//set image bitmap to image view
mainImageview.setImageBitmap(thePic);
}
}
//create helping method cropCapturedImage(Uri picUri)
public void cropCapturedImage(Uri picUri){
//call the standard crop action intent
Intent cropIntent = new Intent("com.android.camera.action.CROP");
//indicate image type and Uri of image
cropIntent.setDataAndType(picUri, "image/*");
//set crop properties
cropIntent.putExtra("crop", "true");
//indicate aspect of desired crop
cropIntent.putExtra("aspectX", 0);
cropIntent.putExtra("aspectY", 0);
//indicate output X and Y
cropIntent.putExtra("outputX", 128);
cropIntent.putExtra("outputY", 256);
//retrieve data on return
cropIntent.putExtra("return-data", true);
//start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, 2);
}
}
这里是保存图片的代码。
public void saveImageToExternalStorage(Bitmap finalBitmap) {
String root =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file1 = new File(myDir, fname);
if (file1.exists())
file1.delete();
try {
FileOutputStream out = new FileOutputStream(file1);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
}
catch (Exception e) {
e.printStackTrace();
}
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this, new String[] { file1.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
}
非常感谢您的帮助。如果这是一个愚蠢的问题,我尽量不麻烦任何人。我真的在尽我最大的努力研究和研究我 using/lifting 的代码的每一部分...再次感谢...
您是否在 api23 及更高版本上对其进行测试?如果是这样...您是否手动请求 WRITE_EXTERNAL_STORAGE 的权限?因为放在 manifest 里是不够的。
代码工作正常...很抱歉浪费您所有的时间和关注...
我刚刚添加了清单以写入内存......
当我从 android 开发人员那里读到有关写入存储的清单时,我认为当您使用 API19 及更高版本时不需要清单...
我目前正在从事一个项目,即捕获图像、裁剪图像、处理图像然后保存处理后的图像。我的问题在于保存处理后的图像。我无法保存处理后的图像。对于捕获的每张图像,捕获的图像将显示在图库中,而不是处理后的图像。我在想,因为捕获图像代码将图像保存到 SD 卡,我无法保存位图上的处理图像......我希望你能启发我我的代码有什么问题。顺便说下代码没有错误。
更具体一点,我正在使用的应用程序捕获图像然后裁剪图像。之后该图像将显示在 imageView 中。处理后,它将再次显示在 imageView 中。当我将图像保存在外部存储器中时,没有任何反应...
这是捕获和裁剪图像的代码
public class MainActivity extends Activity {
ImageView mainImageview;
Button mainButtonTakePhoto;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeControls();
}
private void initializeControls() {
mainImageview = (ImageView)findViewById(R.id.imageView1);
mainButtonTakePhoto = (Button)findViewById(R.id.button3);
mainButtonTakePhoto.setOnClickListener(new OnClickListener() {
@Override
public void onClick (View v) {
/* create an instance of intent
* pass action android.media.action.IMAGE_CAPTURE
* as argument to launch camera */
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
/*create instance of File with name img.jpg*/
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "img.jpg");
/*put uri as extra in intent object*/
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
/*start activity for result pass intent as argument and request code */
startActivityForResult(intent, 1);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//if request code is same we pass as argument in startActivityForResult
if(requestCode==1){
//create instance of File with same name we created before to get image from storage
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "img.jpg");
//Crop the captured image using an other intent
try {
/*the user's device may not support cropping*/
cropCapturedImage(Uri.fromFile(file));
}
catch(ActivityNotFoundException aNFE){
//display an error message if user device doesn't support
String errorMessage = "Sorry - your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
if(requestCode==2){
//Create an instance of bundle and get the returned data
Bundle extras = data.getExtras();
//get the cropped bitmap from extras
Bitmap thePic = extras.getParcelable("data");
//set image bitmap to image view
mainImageview.setImageBitmap(thePic);
}
}
//create helping method cropCapturedImage(Uri picUri)
public void cropCapturedImage(Uri picUri){
//call the standard crop action intent
Intent cropIntent = new Intent("com.android.camera.action.CROP");
//indicate image type and Uri of image
cropIntent.setDataAndType(picUri, "image/*");
//set crop properties
cropIntent.putExtra("crop", "true");
//indicate aspect of desired crop
cropIntent.putExtra("aspectX", 0);
cropIntent.putExtra("aspectY", 0);
//indicate output X and Y
cropIntent.putExtra("outputX", 128);
cropIntent.putExtra("outputY", 256);
//retrieve data on return
cropIntent.putExtra("return-data", true);
//start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, 2);
}
}
这里是保存图片的代码。
public void saveImageToExternalStorage(Bitmap finalBitmap) {
String root =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file1 = new File(myDir, fname);
if (file1.exists())
file1.delete();
try {
FileOutputStream out = new FileOutputStream(file1);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
}
catch (Exception e) {
e.printStackTrace();
}
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this, new String[] { file1.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
}
非常感谢您的帮助。如果这是一个愚蠢的问题,我尽量不麻烦任何人。我真的在尽我最大的努力研究和研究我 using/lifting 的代码的每一部分...再次感谢...
您是否在 api23 及更高版本上对其进行测试?如果是这样...您是否手动请求 WRITE_EXTERNAL_STORAGE 的权限?因为放在 manifest 里是不够的。
代码工作正常...很抱歉浪费您所有的时间和关注... 我刚刚添加了清单以写入内存...... 当我从 android 开发人员那里读到有关写入存储的清单时,我认为当您使用 API19 及更高版本时不需要清单...