Как скрыть представление предварительного просмотра при отображении эффекта наложения для сегментации селфи? ⇐ Android

Форум для тех, кто программирует под Android
Anonymous
Как скрыть представление предварительного просмотра при отображении эффекта наложения для сегментации селфи?

Сообщение Anonymous »

I am using Selfie Segmentation to remove the background and using overlay effect to display it but the probelm is i need to somehow hide the preview and just display the OverlayEffect

[*]Clone this repo
[*]Open in Android Studio
[*]The preview is visible along with the Overlay Effect
< /ol>
Вот код < /p>

Код: Выделить всё

class MainActivity : AppCompatActivity() {

private var imageCapture: ImageCapture? = null
private lateinit var cameraExecutor: ExecutorService

private lateinit var viewFinder: PreviewView
private lateinit var button: Button

private lateinit var greenScreenEffect: OverlayEffect

private val activityResultLauncher =
registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
)
{ permissions ->
// Handle Permission granted/rejected
var permissionGranted = true
permissions.entries.forEach {
if (it.key in REQUIRED_PERMISSIONS && !it.value)
permissionGranted = false
}
if (!permissionGranted) {
Toast.makeText(
baseContext,
"Permission request denied",
Toast.LENGTH_SHORT
).show()
} else {
startCamera()
}
}

lateinit var mask: Bitmap
lateinit var bitmap: Bitmap

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}

viewFinder = findViewById(R.id.viewFinder)
button = findViewById(R.id.image_capture_button)

greenScreenEffect = OverlayEffect(
PREVIEW or IMAGE_CAPTURE or VIDEO_CAPTURE,
5,
Handler(Looper.getMainLooper()),
) {}

button.setOnClickListener {
takePhoto()
}

if (allPermissionsGranted()) {
startCamera()
} else {
requestPermissions()
}

cameraExecutor = Executors.newSingleThreadExecutor()
}

private fun takePhoto() {
// Get a stable reference of the modifiable image capture use case
val imageCapture = imageCapture ?: return

// Create time stamped name and MediaStore entry.
val name = SimpleDateFormat(FILENAME_FORMAT, Locale.US)
.format(System.currentTimeMillis())
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, name)
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
if (Build.VERSION.SDK_INT >  Build.VERSION_CODES.P) {
put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/CameraX-Image")
}
}

// Create output options object which contains file + metadata
val outputOptions = ImageCapture.OutputFileOptions
.Builder(
contentResolver,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
contentValues
)
.build()

// Set up image capture listener, which is triggered after photo has
// been taken
imageCapture.takePicture(
outputOptions,
ContextCompat.getMainExecutor(this),
object : ImageCapture.OnImageSavedCallback {
override fun onError(exc: ImageCaptureException) {
Log.e(TAG, "Photo capture failed: ${exc.message}", exc)
}

override fun
onImageSaved(output: ImageCapture.OutputFileResults) {
val msg = "Photo capture succeeded: ${output.savedUri}"
cameraExecutor.shutdown()
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()

}
}
)
}

private fun startCamera() {

val aspectRatioStrategy = AspectRatioStrategy(
AspectRatio.RATIO_16_9, AspectRatioStrategy.FALLBACK_RULE_NONE
)
val resolutionSelector = ResolutionSelector.Builder()
.setAspectRatioStrategy(aspectRatioStrategy)
.build()

val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

cameraProviderFuture.addListener({
// Used to bind the lifecycle of cameras to the lifecycle owner
val cameraProvider:  ProcessCameraProvider = cameraProviderFuture.get()

// Preview
val preview = Preview.Builder()
.setResolutionSelector(resolutionSelector)
.setTargetRotation(viewFinder.display.rotation)
.build()
.also {
it.surfaceProvider = viewFinder.surfaceProvider
}

// Make the preview view transparent

imageCapture = ImageCapture.Builder()
.setResolutionSelector(resolutionSelector)
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.setTargetRotation(viewFinder.display.rotation)
.build()

val imageAnalysisUseCase = ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build()

imageAnalysisUseCase.setAnalyzer(
ContextCompat.getMainExecutor(this),
SelfieSegmentationAnalyzer(),
)

val paint = Paint()
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_IN)
paint.colorFilter = ColorMatrixColorFilter(
floatArrayOf(
0f, 0f, 0f, 1f, 0f,
0f, 0f, 0f, 1f, 0f,
0f, 0f, 0f, 1f, 0f,
0f, 0f, 0f, 1f, 0f,
),
)

greenScreenEffect.setOnDrawListener { frame ->
if (!::mask.isInitialized || !::bitmap.isInitialized) {
// Do not change the drawing if the frame doesn’t match the analysis
// result.
return@setOnDrawListener true
}

// Clear the previously drawn frame.
frame.overlayCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)

// Draw the bitmap and mask, positioning the overlay in the bottom right corner.
//                val rect = Rect(2 * bitmap.width, 0, 3 * bitmap.width, bitmap.height)
val rect = Rect(0, 0, frame.overlayCanvas.width, frame.overlayCanvas.height)
frame.overlayCanvas.drawBitmap(bitmap, null, rect, null)
frame.overlayCanvas.drawBitmap(mask, null, rect, paint)

true
}

// Select back camera as a default
val cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA

val useCaseGroupBuilder = UseCaseGroup.Builder()
.addUseCase(preview)
.addUseCase(imageCapture!!)
.addUseCase(imageAnalysisUseCase)
.addEffect(greenScreenEffect)

try {
// Unbind use cases before rebinding
cameraProvider.unbindAll()

// Bind use cases to camera
cameraProvider.bindToLifecycle(
this, cameraSelector, useCaseGroupBuilder.build()
)

} catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}

}, ContextCompat.getMainExecutor(this))
}

private fun requestPermissions() {
activityResultLauncher.launch(REQUIRED_PERMISSIONS)
}

private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
ContextCompat.checkSelfPermission(
baseContext, it
) == PackageManager.PERMISSION_GRANTED
}

override fun onDestroy() {
super.onDestroy()
cameraExecutor.shutdown()
}

companion object {
private const val TAG = "CameraXApp"
private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
private val REQUIRED_PERMISSIONS =
mutableListOf(
Manifest.permission.CAMERA
).apply {
if (Build.VERSION.SDK_INT 
// Get foreground probabilities for each pixel. Since ML Kit returns this
// in a byte buffer with each 4 bytes representing a float, convert it to
// a FloatBuffer for easier use.
val maskProbabilities = results.buffer.asFloatBuffer()

// Initialize our mask buffer and intermediate mask bitmap
if (!::maskBuffer.isInitialized) {
maskBitmap = createBitmap(
results.width,
results.height,
Bitmap.Config.ALPHA_8,
)
maskBuffer = ByteBuffer.allocateDirect(
maskBitmap.allocationByteCount,
)
}
maskBuffer.rewind()

// Convert the mask to an A8 image from the mask probabilities.
// We use a line buffer hear to optimize reads from the FloatBuffer.
val lineBuffer = FloatArray(results.width)
for (y in 0.. backgroundRemovalThreshold) {
255.toByte()
} else {
0
},
)
}
}
maskBuffer.rewind()
// Convert the mask buffer to a Bitmap so we can easily rotate and
// mirror.
maskBitmap.copyPixelsFromBuffer(maskBuffer)
val rotation = imageProxy.imageInfo.rotationDegrees
// Transformation matrix to mirror and rotate our bitmaps
val matrix = Matrix().apply {
//                            setScale(-1f, 1f)
//                            preRotate(-rotation.toFloat()) //here
}

// Mirror the ImageProxy
bitmap = Bitmap.createBitmap(
imageProxy.toBitmap(),
0,
0,
imageProxy.width,
imageProxy.height,
matrix,
false,
)

// Rotate and mirror the mask.  When the rotation is 90 or 270, we need
// to swap the width and height.

val (rotWidth, rotHeight) = when (rotation) {
90, 270 ->
Pair(maskBitmap.height, maskBitmap.width)

else ->
Pair(maskBitmap.width, maskBitmap.height)
}
mask = Bitmap.createBitmap(
maskBitmap,
0,
0,
rotWidth,
rotHeight,
matrix
.apply { preRotate(-rotation.toFloat())  },
false,
)
}
.addOnCompleteListener {
// Final cleanup. Close imageProxy for next analysis frame.
imageProxy.close()
}
} else {
imageProxy.close()
}
}
}

}
Я попытался скрыть видимость предварительного просмотра, изменив альфа, изменяя цвет фона на прозрачный, устанавливая поставщика поверхности на нулевый или не устанавливая поставщика поверхности, но все это скрывает эффект наложения

Подробнее здесь: https://stackoverflow.com/questions/797 ... fie-segmen

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