Подтвердить что ты не робот

Android: OpenCV: imwrite всегда возвращает false и не записывает

Этот код использовался, но на Android 4.2 и OpenCV 2.4.4 он терпит неудачу, но я не знаю почему. Может ли кто-нибудь пролить свет на это для меня?

Спасибо за любую помощь.

Баз

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 возвращается false каждый раз. Путь/имя файла так же, как и должно быть ( "storage/emulated/0/Pictures/barry.png" ) для пользователя # 0, а также каталог "Фотографии".

Что может сделать imwrite return false?

Я мог бы преобразовать коврик в bmp и сохранить его сам (что я делаю в другом месте в приложении, отличном от OpenCV), но так как Highgui.imwrite есть, и этот код работал, когда я писал до 2.4.0 и тестирование на Android 3.x, я бы хотел использовать его, если смогу.

Большое спасибо

Баз

4b9b3361

Ответ 1

Я не могу в это поверить. [Facepalm].

Добавьте это в свой файл манифеста Barry:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Кто-нибудь придет и похлопает меня, пожалуйста? Мне удалось удалить разрешение записи из манифеста, так что не должно быть никаких сюрпризов, что он не будет писать...

Doh.

Barry

Ответ 2

На самом деле существуют две возможные проблемы:

  • Android-разрешения.. Чтобы устранить эту проблему, добавьте разрешение манифеста

    "android.permission.WRITE_EXTERNAL_STORAGE"

  • Вы пытаетесь сохранить файл на SD-карту, и ваше устройство подключено к ПК в "Дисковод", Режим. Это означает, что вы разделяете права доступа с ПК. Подключите устройство в режиме "Только зарядка". Чтобы проверить режим подключения, используйте

    Environment.getExternalStorageState(), он вернет общий для "Режим диска" и установлен для "Только для зарядки".

    Я изменил ваш код, и теперь он выглядит как

    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

Будьте осторожны с версиями +4.4 (KitKat), потому что android.permission.WRITE_EXTERNAL_STORAGE не позволяет записывать на внешнюю SD-карту:

Разрешение WRITE_EXTERNAL_STORAGE должно предоставлять только доступ на запись к первичное внешнее хранилище на устройстве. Приложениям не разрешается пишите на внешние внешние устройства хранения, за исключением их каталоги, зависящие от пакета, разрешенные синтезированными разрешениями. Ограничение записи таким образом гарантирует, что система может очищать файлы когда приложения удаляются.

Взгляните на: Запись на SD-карту всегда сбой

Ответ 4

От Android 6 +

Начиная с Android 6.0 (уровень API 23), пользователи предоставляют разрешения для приложений во время работы приложения, а не когда они устанавливают приложение...

И вам нужно добавить что-то вроде:

  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