У меня есть эта функция расширения, чтобы создать растровое изображение с URI

fun Uri.getBitmap(resolver: ContentResolver): Bitmap {
  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
    @Suppress("DEPRECATION")
    return MediaStore.Images.Media.getBitmap(resolver, this)
  } else {
    val source = ImageDecoder.createSource(resolver, this)
    return ImageDecoder.decodeBitmap(source)
  }
}

В Build.VERSION.SDK_INT >= Build.VERSION_CODES.P, поэтому, когда я использую ImageDecoder.createSource, я получаю это исключение:

CvException [org.opencv.core.CvException: OpenCV(4.1.1) /build/master_pack-android/opencv/modules/java/generator/src/cpp/utils.cpp:38: error: (-215:Assertion failed) AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0

Находясь на Build.VERSION.SDK_INT < Build.VERSION_CODES.P, поэтому используя MediaStore.Images.Media.getBitmap, все работает нормально.

Что мне не хватает?

0
shadowsheep 25 Сен 2019 в 19:05

1 ответ

Лучший ответ

Глядя на ImageDecoder Официальный документ, вы можете прочитать:

По умолчанию растровое изображение, созданное imagedecoder (включая то, что находится внутри нанесенного нанесения), будет неизменным (i.e. bitmap # Исзываемые возвраты false), и он обычно будет иметь аппаратное обеспечение Config Bitmap.config. Хотя эти свойства могут быть изменены с SetMutabreReeReewairedire (True)

Поэтому изменение функции расширения путем добавления

setMutableRequired(true)

Таким образом:

fun Uri.getBitmap(resolver: ContentResolver): Bitmap {
  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
    @Suppress("DEPRECATION")
    return MediaStore.Images.Media.getBitmap(resolver, this)
  } else {
    // https://developer.android.com/reference/android/graphics/ImageDecoder
    // CvException [org.opencv.core.CvException: OpenCV(4.1.1) /build/master_pack-android/opencv/modules/java/generator/src/cpp/utils.cpp:38: error: (-215:Assertion failed) AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0
    /*
      By default, a Bitmap created by ImageDecoder (including one that is inside a Drawable)
      will be immutable (i.e. Bitmap#isMutable returns false), and it will typically
      have Config Bitmap.Config#HARDWARE. Although these properties can be changed
      with setMutableRequired(true)
     */
    val source = ImageDecoder.createSource(resolver, this)
    return ImageDecoder.decodeBitmap(source) { decoder, _, _ ->
      decoder.isMutableRequired = true
    }
  }
}

Проблема ушла!

1
shadowsheep 25 Сен 2019 в 16:07