Android: OpenCV: imwrite always returns false and fails to write

匿名 (未验证) 提交于 2019-12-03 01:59:02

问题:

This code used to work but on Android 4.2 and OpenCV 2.4.4 it fails, but I don't know why. Can anyone shed any light on it for me?

Thanks for any help.

Baz

public void SaveImage (Mat mat) {   Mat mIntermediateMat = new Mat();    Imgproc.cvtColor(mRgba, mIntermediateMat, Imgproc.COLOR_RGBA2BGR, 3);    File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);   String filename = "barry.png";   File file = new File(path, filename);    Boolean bool = null;   filename = file.toString();   bool = Highgui.imwrite(filename, mIntermediateMat);    if (bool == true)     Log.d(TAG, "SUCCESS writing image to external storage");   else     Log.d(TAG, "Fail writing image to external storage");   } 

bool comes back false every time. The file path/name is as it should be ("storage/emulated/0/Pictures/barry.png") for User #0 and the directory Pictures is there.

What can make imwrite return false?

I could convert the mat to a bmp and save it myself (which I do elsewhere in a non-OpenCV app) but since Highgui.imwrite is there, and this code used to work when I was writing to 2.4.0 and testing on Android 3.x, I'd like to use it if I can.

Many thanks

Baz

回答1:

I can't believe it. [facepalm].

Add this to your manifest file Barry:

Would somebody come and slap me please? I managed to remove the write permission from the manifest so really there shouldn't be any surprise that it wouldn't write...

Doh.

Barry



回答2:

There are actually two possible problems:

  1. Android permissions. To fix this problem add the permission to the manifest

    "android.permission.WRITE_EXTERNAL_STORAGE"

  2. You are trying to save file to SD card and your device is connected to PC in "Disk drive" mode. It means that you share the access rights with PC. Connect your device in mode "Charge only". To check the connection mode use

    Environment.getExternalStorageState(), it will return shared for "Disk mode" and mounted for "Charge only".

    I modified your code and now it looks like

    public void SaveImage (Mat mat) {    Mat mIntermediateMat = new Mat();    Imgproc.cvtColor(mRgba, mIntermediateMat, Imgproc.COLOR_RGBA2BGR, 3);     File path = new File(Environment.getExternalStorageDirectory() + "/Images/");    path.mkdirs();    File file = new File(path, "image.png");     filename = file.toString();    Boolean bool = Highgui.imwrite(filename, mIntermediateMat);     if (bool)     Log.i(TAG, "SUCCESS writing image to external storage");    else     Log.i(TAG, "Fail writing image to external storage"); } 


回答3:

Take care with versions +4.4 (KitKat) because android.permission.WRITE_EXTERNAL_STORAGE doesn't allow to write on the external SD card:

The WRITE_EXTERNAL_STORAGE permission must only grant write access to the primary external storage on a device. Apps must not be allowed to write to secondary external storage devices, except in their package-specific directories as allowed by synthesized permissions. Restricting writes in this way ensures the system can clean up files when applications are uninstalled.

Take a look to: Writing to SD Card always failing



回答4:

From Android 6+

Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app...

And you need to add something like:

  if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)    {         ActivityCompat.requestPermissions(                 this,                 new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },                 PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);   } 

https://developer.android.com/training/permissions/requesting.html



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!