我想在圆圈内渲染相机预览,如下所示:
我让它在添加到 Activity 的 fragment 中工作。但我想通过将 View 添加到 WindowManager 来显示其他应用程序之上的 View 。
所以我所做的工作是在其他应用程序之上显示 View ,但 SurfaceView 根本不剪辑。另外,我将 SurfaceView 剪裁成圆形,但在一个 fragment 中。
我在这里阅读了很多关于这个主题的答案和文章。关于裁剪 SurfaceView 的信息很少,也没有库可以满足我的要求。我找到的大部分信息只解释了如何将其裁剪为正方形或其他矩形。
添加到 WindowManager 后的样子
我在努力画画
如何剪辑显示在所有 View 上方的 SurfaceView?
SurfaceView 子类
public class CircleSurface extends SurfaceView {
private Path clipPath;
public CircleSurface(Context context) {
super(context);
init();
}
public CircleSurface(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CircleSurface(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setZOrderMediaOverlay(true);
setWillNotDraw(false);
SurfaceHolder sfhTrackHolder = getHolder();
sfhTrackHolder.setFormat(PixelFormat.TRANSPARENT);
clipPath = new Path();
//TODO: define the circle you actually want
clipPath.addCircle(710, 330, 250, Path.Direction.CW);
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.clipPath(clipPath);
super.dispatchDraw(canvas);
}
}
向窗口管理器添加 View 的服务
public class LiveStreamingService extends Service implements SurfaceHolder.Callback {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForeground(startId, getNotification());
}
sharedInstance = this;
// android shouldn't auto restart this service
return START_NOT_STICKY;
}
@Override
public void onCreate() {
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
// camera view
CircleSurface cameraSurfaceView = new CircleSurface(this);
cameraSurfaceView.getHolder().addCallback(this);
wm.addView(cameraSurfaceView, getLayoutParams(360, 270));
}
private WindowManager.LayoutParams getLayoutParams(int width, int height) {
int overlayType = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O
? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
: WindowManager.LayoutParams.TYPE_PHONE;
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
width,
height,
overlayType,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT
);
return layoutParams;
}
// ...
}
更新
似乎相机渲染在某种程度上与 dispatchDraw
方法分开。我可以在 dispatchDraw
中做任何事情,并且相机一直显示为矩形。
最佳答案
为使用 OnPreviewFrame
监听相机预览回调的表面 View 创建了一个绘图线程。
在线程的绘图循环中:
c.drawColor(0, PorterDuff.Mode.CLEAR);
c.drawColor(0x1000000); // magical color that removes everything (like transparency)
if (currentFrame == null) return;
c.clipPath(circleSurfaceView.path);
c.drawBitmap(currentFrame, 0, 0, paint);
我不知道神奇的颜色是什么。我遇到它是幸运的。我尝试过的所有其他方法只会画出黑色或模糊的噪音。
关于android - 如何渲染裁剪成圆形的 SurfaceView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54281206/