gpt4 book ai didi

android - 在 Android 上将 mask 应用于视频预览

转载 作者:太空狗 更新时间:2023-10-29 15:04:55 25 4
gpt4 key购买 nike

我正在尝试在 Android 上的视频源(预览)上应用 mask 。

想法是裁剪设备屏幕上的视频,使其看起来呈圆形。

这是我到目前为止能够完成的事情:

scren grab of app

(忽略视频源中的黑色圆形带,这是 xml 布局中的单独 Assets )

如您所见,我有视频,中间有一个圆孔。我需要相反的东西(即我应该看到“洞”内的视频,其余部分应该是不可见的)。

我正在重写 SurfaceView 的绘制方法并应用 Porter-Duff 模式:

相关代码如下:

package org.dornad.test;

import android.content.Context;
import android.graphics.*;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.IOException;

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private Camera camera;
private final SurfaceHolder holder;
private Bitmap rounderBitmap;
private Paint xferPaint;

public CameraPreview(Context context, Camera camera) {
super(context);

this.camera = camera;
holder = getHolder();
holder.addCallback(this);

this.setDrawingCacheEnabled(true);
}

@Override
public void draw(Canvas canvas) {

Bitmap currentBitmap = get();
int w = currentBitmap.getWidth(), h = currentBitmap.getHeight();

if (rounderBitmap == null)
rounderBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(rounderBitmap);

if (xferPaint == null)
xferPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
xferPaint.setColor(Color.RED);

c.drawCircle(w/2, h/2, 100, xferPaint);
xferPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

canvas.drawBitmap(currentBitmap, 0, 0, null);
canvas.drawBitmap(rounderBitmap, 0, 0, xferPaint);
}

private Bitmap get() {
return this.getDrawingCache();
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
setWillNotDraw(false);
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (IOException e) {
L.d("Error setting camera preview : %s", e.getMessage());
}
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (holder.getSurface() == null) {
return;
}
try {
camera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop an non-existent preview
}

try {
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (IOException e) {
L.d("Error setting camera preview : %s", e.getMessage());
}
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in the Activity/Fragment.
}
}

根据 Porter-Duff 混合模式的视觉指南:

XferModes Example

我正在寻找的应该是 PorterDuff.Mode.XOR,但我得到的却是带有红色填充的圆圈,而不是视频源。 (我知道红色来自 xferPaint.setColor 调用)

有什么想法吗?

最佳答案

您正在使用 xferPaint 做两件事:

  • 在缓冲区中画一个圆
  • 在预览之上绘制缓冲区

并且您在使用 DST_IN 将每个渲染器上的圆重新绘制到 rounderBitmap 中!

我认为如果您重新排序您的代码,您可能会得到想要的结果(未测试):

    Bitmap currentBitmap = get();
int w = currentBitmap.getWidth(), h = currentBitmap.getHeight();

if (rounderBitmap == null) {
rounderBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(rounderBitmap);
Paint holePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
holePaint.setColor(Color.RED);
c.drawCircle(w / 2, h / 2, 100, holePaint);
}

if (xferPaint == null) {
Paint xferPaint = new Paint();
xferPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
}

canvas.drawBitmap(currentBitmap, 0, 0, null);
canvas.drawBitmap(rounderBitmap, 0, 0, xferPaint);

另外,如果它有效,那么您可能需要考虑:

  • rounderBitmap 分配为 200x200 位图,而不是 w x h
  • drawCircle(100, 100, 100
  • drawBitmap 时将 rounderBitmap 定位在 w/2-100h/2-100。<

通常,您可以尝试转储位图以查看它是否是您想要的(中间有一个圆圈的图像(具有正确的颜色/alpha):

static int counter;
// inside draw:
File out = new File(getContext().getExternalCacheDir(), "frame_"+ counter++ +".png");
Bitmap.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(out));
Log.d("DEBUG", "Written: " + out);

免责声明:我没有使用 PorterDuff 的经验,以上只是一般性建议。

关于android - 在 Android 上将 mask 应用于视频预览,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22947387/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com