【问题标题】:Android: Saving Bitmap to External MemoryAndroid:将位图保存到外部存储器
【发布时间】:2016-05-11 13:27:24
【问题描述】:

我目前正在从事一个拍摄图像、裁剪图像、处理图像然后保存处理后的图像的项目。我的问题在于保存处理后的图像。我无法保存处理后的图像。对于捕获的每个图像,捕获的图像都显示在图库中,而不是处理后的图像。我在想,因为捕获图像代码将图像保存到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);
                }
            });

}

非常感谢您的帮助。如果这是一个愚蠢的问题,我会尽量不打扰任何人。而且我真的在尽我最大的努力研究和研究我正在使用/提升的代码的每一部分......再次感谢......

【问题讨论】:

  • void saveImageToExternalStorage()。使它成为一个布尔函数。因为函数返回值应该告诉您是否确实已完成保存。您没有检查 mkdirs 的返回值。如果其他地方出现问题,也不返回 null。
  • 裁剪意图工作得很好......
  • 如果可行,我将尝试将其设为布尔值并进行编辑。谢谢greenapps!

标签: android image memory save external


【解决方案1】:

您是否在 api23 及更高版本上对其进行测试?如果是这样...您是否手动请求 WRITE_EXTERNAL_STORAGE 的权限?因为把它放在清单中是不够的。

【讨论】:

    【解决方案2】:

    代码运行良好...很抱歉浪费您所有的时间和关注... 我刚刚添加了清单以写入内存... 当我从 android 开发人员那里读到关于写入存储的清单时,我认为当您使用 API19 及更高版本时不需要清单...

    【讨论】:

      猜你喜欢
      • 2015-06-14
      • 2013-05-17
      • 2011-12-14
      • 2015-01-26
      • 1970-01-01
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      • 2011-10-10
      相关资源
      最近更新 更多