Как предварительно обработать изображение в Android (Kotlin)?Android

Форум для тех, кто программирует под Android
Ответить
Гость
 Как предварительно обработать изображение в Android (Kotlin)?

Сообщение Гость »


Я хочу показать размытый предварительный просмотр в Android с помощью Camera2 (в Jetpack Compose).

Что бы я ни пытался, я даже не могу передать изображение из ImageReader в SurfaceView или TextureView. Вот последнее, что я пробовал:

Предварительный просмотр представляет собой SurfaceView:

AndroidView( модификатор = Модификатор.fillMaxSize(), фабрика = {контекст -> SurfaceView(контекст).apply { LayoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, ) }.также { it.holder.addCallback(объект: SurfaceHolder.Callback { переопределить fun SurfaceCreated(holder: SurfaceHolder) { объем.запуск { val camera = CameraHandler.openCamera(контекст); camera.startBlurredPreview( это.держатель.поверхность, контекст, предварительный просмотрРазмер, ); } } переопределить забавную поверхностьChanged( держатель: SurfaceHolder, формат: Целый, ширина: Int, высота: Int ) { } переопределить fun SurfaceDestroyed(holder: SurfaceHolder) { } }) } } ) а логика для камеры здесь:

class CameraHandler( частный менеджер валов: CameraManager, частное устройство Val: CameraDevice, частный обработчик val: Handler, частный поток val: HandlerThread, частный объектив val: Int = CameraCharacteristics.LENS_FACING_BACK, ) { частный lateinit var imageReader: ImageReader val характеристики: CameraCharacteristics get() = менеджер.getCameraCharacteristics(lens.toString()) @RequiresApi(Build.VERSION_CODES.P) частная приостановка развлечения createCaptureSession( выходные данные: List, ): CameraCaptureSession = suspendCancellableCoroutine {cont -> // Мне действительно не хочется использовать устаревший метод, но есть // для нового метода абсолютно нет документации. устройство.createCaptureSession( выходы, объект: CameraCaptureSession.StateCallback() { переопределить удовольствие onConfigured(session: CameraCaptureSession) { cont.resume(сессия) } переопределить удовольствие onConfigureFailed(session: CameraCaptureSession) { cont.resumeWithException(RuntimeException("Не удалось настроить сеанс")) } }, обработчик, ) } @RequiresApi(Build.VERSION_CODES.P) приостановить веселье startBlurredPreview( поверхность: Поверхность, контекст: Контекст, размер: Размер? = ноль, ) { val readSize = размер?: getScreenSize(context).let { Размер( it.ширина / 10, it.height / 10, ) } println("Создание программы чтения изображений размером $readerSize") val imageReader = ImageReader.newInstance( читательSize.width, ReadSize.height, Формат изображения.YUV_420_888, IMAGE_BUFFER_SIZE, ) val rs = RenderScript.create(контекст) val BluScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)) imageReader.setOnImageAvailableListener({читатель -> val image = reader.acquireLatestImage() ?: return@setOnImageAvailableListener // ЗДЕСЬ я борюсь. Как размыть изображение? Как отправить его на Surface? Код ниже — последнее решение, которое я пробовал до сих пор.... // Показать изображение yuv на экране val yBuffer = image.planes[0].buffer val uBuffer = image.planes[1].buffer val vBuffer = image.planes[2].buffer val ySize = yBuffer.remaining() val uSize = uBuffer.remaining() val vSize = vBuffer.remaining() val yData = ByteArray(ySize) val uData = ByteArray(uSize) val vData = ByteArray(vSize) yBuffer.get(yData) uBuffer.get(uData) vBuffer.get(vData) val yuvImage = YuvImage(yData, ImageFormat.YUY2, readSize.width, readSize.height, null,) val out = ByteArrayOutputStream() yuvImage.compressToJpeg(Rect(0, 0, readSize.width, readSize.height), 100, out) val imageBytes = out.toByteArray() val растровое изображение = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size) если (растровое изображение == ноль) { return@setOnImageAvailableListener } println("Размер растрового изображения: ${bitmap.width}x${bitmap.height}") val холст = поверхность.lockCanvas(null)!! Canvas.drawBitmap(растровое изображение, 0f, 0f, ноль) поверхность.unlockCanvasAndPost(холст) // Выпускать изображение.закрыть() }, обработчик) println("Создание сеанса захвата") val выходы = listOf(imageReader.surface) val session = createCaptureSession (выходные данные) println("Создание запроса на захват") val captureRequest = device.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW) captureRequest.addTarget(imageReader.surface) println("Установка повторяющегося запроса") session.setRepeatingRequest( захватRequest.build(), нулевой, обработчик, ) } сопутствующий объект { константное значение IMAGE_BUFFER_SIZE = 2 весело getCameraManager( контекст: Контекст, ): CameraManager = getSystemService(context, CameraManager::class.java)!! весело createThread(): HandlerThread = HandlerThread("CameraHandler").apply { start() } весело createHandler(thread: HandlerThread): Handler = Handler(thread.looper) @SuppressLint("Миссингпермиссион") приостановить веселье openCamera( менеджер: CameraManager, cameraId: строка, поток: HandlerThread, ): CameraHandler = suspendCancellableCoroutine {cont -> обработчик val = createHandler(поток) Manager.openCamera(cameraId, объект: CameraDevice.StateCallback() { переопределить удовольствие onOpened(device: CameraDevice) { продолжение.резюме( КамераХандлер( менеджер, устройство, обработчик, нить, ) ) } переопределить fun onDisconnected(device: CameraDevice) { } переопределить fun onError(device: CameraDevice, error: Int) { } }, обработчик) } приостановить веселье openCamera( контекст: Контекст, ): CameraHandler { val менеджер = getCameraManager(контекст) val cameraId = менеджер.cameraIdList.first() вал нить = createThread() вернуть openCamera (менеджер, cameraId, поток) } } } Примечание: Изменение формата на ImageType.JPEG работает, но, поскольку мне нужен предварительный просмотр в реальном времени, к сожалению, это неприменимо.

Иногда при попытке различных решений появлялась ошибка Не удалось создать декодер изображения с сообщением «нереализовано», но я не мог ее исправить.

Вот все решения, которые я пробовал:
[*]Как преобразовать android.media.Image в растровый объект? [*]Как преобразовать изображение YUV_420_888 в растровое изображение [*]Отображение изображения YUV в Android [*]https://blog.minhazav.dev/how-to-conver ... p-or-jpeg/ [*]https://blog.neteril.org/blog/2013/08/1 ... n-android/ [*]D/skia: --- Не удалось создать декодер изображения с сообщением «не реализовано».
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»