Как сделать SurfaceView обрезанным по кругу? - PullRequest
0 голосов
/ 21 января 2019

Я хочу визуализировать предварительный просмотр камеры внутри круга, например:

Я работаю с фрагментом, добавленным к действию.Но я хотел бы показать вид над другими приложениями, добавив его в WindowManager.

Итак, я работаю, показывая виды над другими приложениями, но SurfaceView вообще не обрезает.И отдельно у меня есть SurfaceView отсечения по кругу, но фрагментом.

Я прочитал много ответов здесь и статей по этой теме.Существует очень мало информации об обрезке SurfaceView, и нет библиотеки, которая делает то, что я хочу.Большая часть информации, которую я нашел, объясняет только, как обрезать ее до квадрата или другого прямоугольника.

Как это выглядит при добавлении в WindowManager

Япытается перетащить

Как я могу обрезать 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);
    }
}

Сервис, который добавляет виды в диспетчер окон

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, и камера продолжает показывать прямоугольник.

1 Ответ

0 голосов
/ 22 января 2019

Создан поток рисунка для вида поверхности, который прослушивает обратный вызов предварительного просмотра камеры с помощью OnPreviewFrame.

Внутри цикла рисования потока:

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);

Понятия не имею, чтоВолшебный цвет есть.Я наткнулся на это по счастливой случайности.Все остальное, что я пробовал, просто рисовало черный или нечеткий шум.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...