如何将视频视图转换为圆形?

Posted

技术标签:

【中文标题】如何将视频视图转换为圆形?【英文标题】:How to transform a videoview into a circular shape? 【发布时间】:2018-02-12 21:34:08 【问题描述】:

我想在videoview 中全屏播放视频,一段时间后我想cropcircular view

我怎样才能做到这一点?

【问题讨论】:

【参考方案1】:

另一种方法是将这种类型的图像叠加在您的 videoview Relative 或 FrameLayout 上(Circuler 是透明的,因此 videoview 只会在圆圈中可见)

默认情况下,让这个 imageView 的可见性消失,并在需要时更改它的运行时可见性。

可能对您有帮助

【讨论】:

【参考方案2】:

有更好的方法。

您可以创建自定义 SurfaceView。这实际上将视图剪辑为圆形。从这个自定义视图中,您可以将显示设置为 MediaPlayer 对象。

public class VideoSurfaceView extends SurfaceView 

    private final static String TAG = "VideoSurfaceView";
    private Path clipPath;
    private boolean isCircular;

    public VideoSurfaceView(Context context) 
        super(context);
        init();
    

    public VideoSurfaceView(Context context, AttributeSet attrs) 
        super(context, attrs);
        init();
    

    public VideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) 
        super(context, attrs, defStyleAttr);
        init();
    

    private void init() 
        clipPath = new Path();
    

    @Override
    protected void dispatchDraw(Canvas canvas) 
        if (this.isCircular)
            canvas.clipPath(clipPath);
        super.dispatchDraw(canvas);
    

    /**
     * Crops the view in circular shape
     * @param centerX
     * @param centerY
     * @param radius
     */
    public void cropCircle(float centerX, float centerY, int radius) 
        Log.i(TAG, "cropCircle: x=" + centerX + " ,y= " + centerY + ", radius=" + radius);
        clipPath.addCircle(centerX, centerY, radius, Path.Direction.CW);
    

    /**
     * Sets the flag for cropping the view in circular shape
     * @param isCircular
     */
    public void setCircular(boolean isCircular) 
        this.isCircular = isCircular;
        invalidate();
    

在您的活动中,您可以实现 SurfaceHolder.Callback 并在覆盖的方法中设置 MediaPlayer 的显示。

public class MainActivity extends AppCompatActivity implements MediaPlayer.OnCompletionListener, SurfaceHolder.Callback 
    private final static String TAG = "MainActivity";

    @BindView(R.id.activity_main_video_surface_view)
    protected VideoSurfaceView videoView;


    private Handler handler;
    private boolean inCircleMode;

    private final static int CIRCULAR_INTERVAL = 5000;
    private final static int MINIMUM_CARD_HEIGHT = 300;
    private final static int MAXIMUM_CARD_HEIGHT = 500;

    //Parameters for video view.
    private int cropCenterX;
    private int cropCenterY;
    private int cropRadius;
    private int croppedLayoutWidth;
    private int croppedLayoutHeight;
    private int fullLayoutWidth;
    private int fullLayoutHeight;

    private MediaPlayer player;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        initParameters();
    

    /**
     * Initialise the parameters used.
     */
    private void initParameters() 

        SurfaceHolder holder = videoView.getHolder();
        holder.addCallback(this);

        player = MediaPlayer.create(this, R.raw.bird_s);
        player.setOnCompletionListener(this);

        //Setting the video with proper aspect ratio.
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int height = displayMetrics.heightPixels;
        int width = displayMetrics.widthPixels;
        int dimenFull[] = Utility.getVideoDimensions(player, width, height);
        fullLayoutWidth = dimenFull[0];
        fullLayoutHeight = dimenFull[1];

        setVideoLayout();
    

    //Runnable for switching the views from circular video to full screen video.
    private Runnable runnable = new Runnable() 
        @Override
        public void run() 
            inCircleMode = !inCircleMode;

            setVideoLayout();
            handler.postDelayed(runnable, CIRCULAR_INTERVAL);
        
    ;

    /**
     * Calculates the dimensions required for cropped video view.
     */
    private void calculateCroppedParams() 
        int dimen[] = Utility.getVideoDimensions(player, 100, 100); 
        croppedLayoutWidth = dimen[0];
        croppedLayoutHeight = dimen[1];

        cropRadius = croppedLayoutWidth / 2;
        cropCenterX = cropRadius;
        cropCenterY = cropRadius;
    

    /**
     * Change the layout dimensions for video view.
     */
    private void setVideoLayout() 
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) videoView.getLayoutParams();

        //Changing the margin, width & height of videoView.
        layoutParams.setMargins(0, inCircleMode ? cardView.getVideoMargin() : 0, 0, 0);
        layoutParams.width = inCircleMode ? croppedLayoutWidth : fullLayoutWidth;
        layoutParams.height = inCircleMode ? croppedLayoutHeight : fullLayoutHeight;
        layoutParams.addRule(inCircleMode ? RelativeLayout.CENTER_HORIZONTAL : RelativeLayout.CENTER_IN_PARENT);

        videoView.cropCircle(cropCenterX, cropCenterY, cropRadius);
        videoView.setCircular(inCircleMode);
        videoView.setLayoutParams(layoutParams);
    

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) 

    

    @Override
    public void onLayout() 
        Log.i(TAG, "onLayout: starting runnable");
        calculateCroppedParams();
        player.start();
    

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) 
        player.setDisplay(surfaceHolder);
    

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) 

    

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) 

    

    @Override
    protected void onStop() 
        Log.i(TAG, "onStop");
        super.onStop();
     

    @Override
    protected void onRestart() 
        super.onRestart();

    

    @Override
    protected void onPause() 
        super.onPause();
        if (player != null && player.isPlaying())
            player.pause();
    

    @Override
    protected void onResume() 
        super.onResume();
        if (player != null && !player.isPlaying())
            player.start();
    

有关如何将视频裁剪成不同形状的更多详细信息,请查看此博文VideoInShapes。

希望这会有所帮助。

?快乐编码?

【讨论】:

以上是关于如何将视频视图转换为圆形?的主要内容,如果未能解决你的问题,请参考以下文章

quartus如何将原理图转成verilog格式

FFMPEG为视频添加圆形蒙版,转换为黑白并连接

Android 共享元素转换:将 ImageView 从圆形转换为矩形,然后再转换回来

如何把ARCGIS图转成CAD图

全景图转局部平面视图原理详解

如何将 UIButton 转换为圆形?