1 /*
2  * Copyright 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.camera.integration.view
18 
19 import android.graphics.Bitmap
20 import android.graphics.Canvas
21 import android.graphics.ColorMatrixColorFilter
22 import android.graphics.Paint
23 import androidx.camera.core.CameraEffect
24 import androidx.camera.core.ImageProcessor
25 import androidx.camera.core.ImageProcessor.Response
26 import androidx.camera.core.ImageProxy
27 import androidx.camera.core.imagecapture.RgbaImageProxy
28 import androidx.camera.core.impl.utils.executor.CameraXExecutors.mainThreadExecutor
29 
30 /** A image effect that applies the same tone mapping as [ToneMappingSurfaceProcessor]. */
31 class ToneMappingImageEffect :
<lambda>null32     CameraEffect(IMAGE_CAPTURE, mainThreadExecutor(), ToneMappingImageProcessor(), {}) {
33 
isInvokednull34     fun isInvoked(): Boolean {
35         return (imageProcessor as ToneMappingImageProcessor).processoed
36     }
37 
38     private class ToneMappingImageProcessor : ImageProcessor {
39 
40         var processoed = false
41 
processnull42         override fun process(request: ImageProcessor.Request): Response {
43             processoed = true
44             val inputImage = request.inputImage as RgbaImageProxy
45             val bitmap = inputImage.createBitmap()
46             applyToneMapping(bitmap)
47             val outputImage = createOutputImage(bitmap, inputImage)
48             inputImage.close()
49             return Response { outputImage }
50         }
51 
52         /** Creates output image */
createOutputImagenull53         private fun createOutputImage(newBitmap: Bitmap, imageIn: ImageProxy): ImageProxy {
54             return RgbaImageProxy(
55                 newBitmap,
56                 imageIn.cropRect,
57                 imageIn.imageInfo.rotationDegrees,
58                 imageIn.imageInfo.sensorToBufferTransformMatrix,
59                 imageIn.imageInfo.timestamp
60             )
61         }
62 
63         /** Applies the same color matrix as [ToneMappingSurfaceProcessor]. */
applyToneMappingnull64         private fun applyToneMapping(bitmap: Bitmap) {
65             val paint = Paint()
66             paint.colorFilter =
67                 ColorMatrixColorFilter(
68                     floatArrayOf(
69                         0.5F,
70                         0.8F,
71                         0.3F,
72                         0F,
73                         0F,
74                         0.4F,
75                         0.7F,
76                         0.2F,
77                         0F,
78                         0F,
79                         0.3F,
80                         0.5F,
81                         0.1F,
82                         0F,
83                         0F,
84                         0F,
85                         0F,
86                         0F,
87                         1F,
88                         0F,
89                     )
90                 )
91             val canvas = Canvas(bitmap)
92             canvas.drawBitmap(bitmap, 0F, 0F, paint)
93         }
94     }
95 }
96