如何绘制如图所示带边框的椭圆形相机屏幕
带椭圆形外观与边框的相机屏幕实现方案
效果参考:
核心实现逻辑
- 限定相机预览内容仅在椭圆区域内可见
- 外层叠加对应样式的椭圆边框,可根据需求调整边框颜色、粗细参数
常见场景实现代码
前端Web端实现(CSS + HTML)
<div class="camera-container"> <video id="camera-feed" autoplay></video> </div>
.camera-container { /* 自定义尺寸 */ width: 320px; height: 480px; /* 椭圆裁剪,可调整参数适配不同椭圆弧度 */ border-radius: 50% / 35%; border: 3px solid #fff; overflow: hidden; position: relative; } #camera-feed { width: 100%; height: 100%; object-fit: cover; }
Android端自定义View实现(Kotlin)
class OvalCameraPreview @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : FrameLayout(context, attrs, defStyleAttr) { private val clipPath = Path() // 边框画笔参数可自定义 private val borderPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = Color.WHITE style = Paint.Style.STROKE strokeWidth = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 3f, resources.displayMetrics ) } override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { super.onSizeChanged(w, h, oldw, oldh) clipPath.reset() clipPath.addOval(RectF(0f, 0f, w.toFloat(), h.toFloat()), Path.Direction.CW) } override fun dispatchDraw(canvas: Canvas) { canvas.save() canvas.clipPath(clipPath) super.dispatchDraw(canvas) canvas.restore() // 绘制边框,缩进1px避免边框被裁切 val borderWidth = borderPaint.strokeWidth / 2 canvas.drawOval( RectF(borderWidth, borderWidth, width - borderWidth, height - borderWidth), borderPaint ) } }
iOS端实现(Swift)
import UIKit import AVFoundation class OvalCameraPreview: UIView { override class var layerClass: AnyClass { return AVCaptureVideoPreviewLayer.self } var previewLayer: AVCaptureVideoPreviewLayer { return layer as! AVCaptureVideoPreviewLayer } override func layoutSubviews() { super.layoutSubviews() // 裁剪为椭圆 let maskLayer = CAShapeLayer() maskLayer.path = UIBezierPath(ovalIn: bounds).cgPath layer.mask = maskLayer // 添加边框 layer.borderColor = UIColor.white.cgColor layer.borderWidth = 3 } }
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

