Uniapp自定义相机界面

Uniapp是一款入门门槛比较低的跨平台开发方案,一套代码可以生成Android、IOS、H5、微信\QQ\支付宝\头条\飞书等若高个平台的小程序,因此很多中小型公司都会考虑用这种方案来实现业务需求;最近公司就要在原有功能上增加水印相机功能,原本如果是原生的Android或IOS很容易实现,不过因为项目是用uniapp搭建的,发现uniapp只能简单调用系统的相机来拍照或录像,哎,可是我们的设计图可是要自定义界面的,这里就卡死了,于是开始寻找解决方案,于是在官网找插件,(看到其他原生相机相关插件的价格,心里拔凉拔凉的,基本都是几百到上千起步,关键这玩意老板不给报销啊),不过也有收获,那就是知道了肯定是可以弄出来自定义界面的效果的,也算吃了半颗定心丸,uniapp这个原生插件的功能(反正就是你可以在Android或IOS端用原生代码来实现功能,然后打包给Uniapp的代码调用),喜出望外呀!于是立刻着手研究原生插件,好在之前好几年的原生Android开发经验,网上找了下资料,封装了一个自定义相机类,不过还是费了老劲了,因为不熟悉Uniapp下的原生插件开发原理,走了很多弯路,所幸还是做出来了一个仅支持Android端的原生插件。乘胜追击!又开始摸索IOS端,因为对IOS端的Object-c和swift都不熟悉,网上找了例子看起来也挺费劲,研究了三天,github上下了十几个demo,一一看完,总算有了个眉目(说句题外话,swift代码风格真的比OC要轻巧很多),一款新的跨Android/IOS两端的原生插件诞生了!最近又优化了一波内容更新到了2.0版本:上图–>

下面展示一些 内联代码片

这个是Android端实现原生插件的方法,返回一个FrameLayout组件便于后面的扩展,addView添加了一个SurfaceView用于显示摄像头的预览效果
   @Override
    protected FrameLayout initComponentHostView(Context context) {
        FrameLayout frameLayout = new FrameLayout(context);
        UniLogUtils.e("绘制帧布局;;;");
        SurfaceView surfaceView = new SurfaceView(context);
        frameLayout.addView(surfaceView);
        if (mHolder == null) {
            mHolder = surfaceView.getHolder();

            mHolder.addCallback(new SurfaceHolder.Callback() {
                @Override
                public void surfaceCreated(SurfaceHolder holder) {
//                    UniLogUtils.e("开始绘制:");
//                    Canvas canvas = holder.lockCanvas();
//                    Paint paint = new Paint();
//                    paint.setColor(Color.WHITE);
//                    paint.setTextSize(22);
//                    canvas.drawText(locationAddress,200,300,paint);
//                    holder.unlockCanvasAndPost(canvas);
//                    UniLogUtils.e("结束绘制:");
                    initCamera();
                }

                @Override
                public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

                }

                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {

                }
            });
        }

        return frameLayout;
    }

IOS端的实现代码,相比Android简单很多,loadView里返回了一个UIView对象,原生插件有两种模式,module和component,简单说就是前者重点在功能,后者重点在界面。viewDidLoad里配置了AVCaptureSession的一些信息,拍照录像都需要使用AVCaptureSession来完成

- (UIView *)loadView {
    NSLog(@"插件日志:loadView");
    return [UIView new];
}

- (void)viewDidLoad {
    NSLog(@"插件日志:viewDidLoad");
    
    self.session = [[AVCaptureSession alloc] init];
    
    //创建一个AVCaptureMovieFileOutput 实例,用于将Quick Time 电影录制到文件系统
    self.movieOutput = [[AVCaptureMovieFileOutput alloc]init];
    //输出连接 判断是否可用,可用则添加到输出连接中去
    if ([self.session canAddOutput:self.movieOutput])
    {
        [self.session addOutput:self.movieOutput];
    }
    
    //     拿到的图像的大小可以自行设定
    //    AVCaptureSessionPresetHigh
    //    AVCaptureSessionPreset320x240
    //    AVCaptureSessionPreset352x288
    //    AVCaptureSessionPreset640x480
    //    AVCaptureSessionPreset960x540
    //    AVCaptureSessionPreset1280x720
    //    AVCaptureSessionPreset1920x1080
    //    AVCaptureSessionPreset3840x2160
    self.session.sessionPreset = AVCaptureSessionPreset1920x1080;
    
    //AVCaptureStillImageOutput 实例 从摄像头捕捉静态图片
    self.imageOutput = [[AVCaptureStillImageOutput alloc]init];
    //配置字典:希望捕捉到JPEG格式的图片
    self.imageOutput.outputSettings = @{AVVideoCodecKey:AVVideoCodecJPEG};
    if ([self.session canAddOutput:self.imageOutput]) {
        [self.session addOutput:self.imageOutput];
    }

    self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError * error = nil;
    self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:&error];
    
    if (self.input) {
        [self.session addInput:self.input];
    }else{
        NSLog(@"Input Error:%@",error);
    }

    //预览层的生成
    self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
    
    // 直接取用本组件的bounds来做定位,因为本组件的bounds是uniapp传过来的css宽高设置过的
    self.previewLayer.frame = self.view.bounds; //预览层填充视图

    // AVLayerVideoGravityResizeAspectFill 等比例填充,直到填充满整个视图区域,其中一个维度的部分区域会被裁剪
    // AVLayerVideoGravityResize 非均匀模式。两个维度完全填充至整个视图区域
    // AVLayerVideoGravityResizeAspect 等比例填充,直到一个维度到达区域边界
    self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    [self.view.layer addSublayer:self.previewLayer];

    [self.session startRunning];
}

插件地址:link
效果展示:
录像功能
相机功能

本课程讲了Vue3+Vue2+Uni-app(uniapp)入门基础与实战,其中还重点讲解了ES6、TypeScript这些基础知识,实战由两大价值5000元的真实企业级项目组成,分别是仿京东电商网站和仿美团微信点餐小程序,同时两大项目代码全部赠送,还赠送前后端架构模板,工作中直接使用。VUE和uni-app是目前热门的前端框架,本课程教你如何快速学会VUE和uni-app并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己封装组件和插件,正式上线白屏问题,性能优化、解决iphoneX“刘海”兼容性问题、微信支付、微信授权登录,获取位置在地图上显示,获取用户所在的城市和街道信息,微信小程序发布审核等。对正在工作当中或打算学习VUE和uni-app高薪就业的你来说,那么这门课程便是你手中的葵花宝典。学习技巧:学习当中不要只看,一定要多敲代码,如果碰到某一个知识点不是很明白,不要钻牛角尖,千万不要因为一个点,放弃整个森林,接着往下学,硬着头皮开发项目。只要能亲自开发一个完整的项目,你会发现不明白的地方自然而然就明白了,项目做出来就真正的学会了。此vue和uni-app课程以面试和实战为基础进行讲解,每个知识点都会让你知道在实际项目开发中如何使用,学习后,可以开发大型项目,增强逻辑思维,至少让你拥有3年以上开发经验的实力!代码和ppt均可下载!免费提供《企业级完整实战项目接口文档》,绝对可用
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值