IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> iOS-自定义相机拍照获取指定区域图片 -> 正文阅读

[移动开发]iOS-自定义相机拍照获取指定区域图片

功能并不难,之所以被难住是因为把问题想复杂了,记录一下。

自定义的相机拍照使用AVCaptureSession,获取指定区域图片使用图片裁切功能,重点在于不能直接使用AVCaptureSession获取到的图片,需要对图片进行放大处理然后再裁切。

自定义相机

@property (nonatomic, strong) AVCaptureSession *captureSession; // 会话
@property (nonatomic, strong) AVCaptureDevice * captureDevice;   // 输入设备
@property (nonatomic, strong) AVCaptureDeviceInput * captureDeviceInput; // 输入源
@property (nonatomic, strong) AVCapturePhotoOutput *photoOutput;    // 图像输出
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer; // 预览画面
@property (nonatomic, strong) AVCapturePhotoSettings *photoSettings;    // 图像设置
@property (nonatomic, assign) AVCaptureDevicePosition position;


#pragma mark - 创建会话
-(AVCaptureSession *)captureSession{
    if (!_captureSession) {
        _captureSession = [[AVCaptureSession alloc] init];
        _captureSession.sessionPreset = AVCaptureSessionPresetPhoto; // 画质
    }
    return _captureSession;
}


#pragma mark - 创建输入设备
-(AVCaptureDevice *)captureDevice{
    if (!_captureDevice) {
    //        设置默认前置摄像头
    _captureDevice = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionBack];
    }
    return _captureDevice;
}

#pragma mark - 创建输入源
-(AVCaptureDeviceInput *)captureDeviceInput{
    if (!_captureDeviceInput) {
        _captureDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:self.captureDevice error:nil];
    }
    return _captureDeviceInput;
}

#pragma mark - 创建图像输出
-(AVCapturePhotoOutput *)photoOutput{
    if (!_photoOutput) {
        _photoOutput = [[AVCapturePhotoOutput alloc] init];
    }
    return _photoOutput;
}


-(AVCaptureVideoPreviewLayer *)previewLayer{
    if (!_previewLayer) {
        _previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
        _previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    }
    return _previewLayer;
}


- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self.layer insertSublayer:self.previewLayer atIndex:0];
        // 5. 连接输入与会话
        if ([self.captureSession canAddInput:self.captureDeviceInput]) {
            [self.captureSession addInput:self.captureDeviceInput];
        }
        // 6. 连接输出与会话
        if ([self.captureSession canAddOutput:self.photoOutput]) {
            [self.captureSession addOutput:self.photoOutput];
        }
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationWillEnterForegroundNotification object:nil];
    }
    return self;
}

#pragma mark - 开始运行
-(void)startRunning {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        [self.captureSession startRunning];
    });
}


#pragma mark - 停止运行
-(void)stopRunning{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        [self.captureSession stopRunning];
    });
}

#pragma mark - 拍照
-(void)shutterCamera {
    
    self.photoSettings = [AVCapturePhotoSettings photoSettingsWithFormat:@{AVVideoCodecKey:AVVideoCodecTypeJPEG}];
    [self.photoSettings setFlashMode:self.mode];
    if (!self.previewLayer || !self.photoOutput || !self.photoSettings) {
        return;
    }
    if (self.captureSession.isRunning == YES) {
        [self.photoOutput capturePhotoWithSettings:self.photoSettings delegate:self];
    }
}



加上相框和按钮的效果:

?拍照回调代理方法获取图片:

#pragma mark - 拍照回调代理
- (void)captureOutput:(AVCapturePhotoOutput *)output didFinishProcessingPhoto:(AVCapturePhoto *)photo error:(NSError *)error{
    if (!error) {
        NSData *imageData = [photo fileDataRepresentation];
        UIImage *image = [UIImage imageWithData:imageData];
        //保存原始图片
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
        
        CGFloat width = self.previewLayer.frame.size.width;
        CGFloat height = self.previewLayer.frame.size.height;
        CGSize size = CGSizeMake(width, height);
        //使用的SDWebImage提供的图片缩放处理方法
        UIImage *scaledImage = [image sd_resizedImageWithSize:size scaleMode:(SDImageScaleModeAspectFill)];
        //保存放大后的图片
        UIImageWriteToSavedPhotosAlbum(scaledImage, nil, nil, nil);
        
        //使用的SDWebImage提供的图片裁切处理方法
        UIImage *targetImage = [scaledImage sd_croppedImageWithRect:CGRectMake(self.clipArea.origin.x, self.clipArea.origin.y, self.clipArea.size.width, self.clipArea.size.height)];
        //图片翻转
        UIImage *newImage = [UIImage imageWithCGImage:targetImage.CGImage scale:1.0f orientation:(UIImageOrientationLeft)];
        //保存裁切后图片
        UIImageWriteToSavedPhotosAlbum(newImage, nil, nil, nil);
        if (image) {
            [self saveImageWithImage:newImage];
        }
    }
}

需要注意的是,获取到的原始图片内容尺寸要比拍照屏幕尺寸大而且是按照宽度自适应的,而我们需要的虚线框中的内容是从全屏宽高的图片中裁切出来的:

?

?左边是获取到的原始图片,右边是我们通过摄像头看到的内容,右边是左边图片等比放大到高度与屏幕高度一样的效果,所以要对原始图片进行放大处理,然后再根据虚线框的位置frame裁切要想的内容。

至于为什么AVCaptureSession获取到的全屏图片内容要比我们看到的内容要多,还得继续查找原因。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章           查看所有文章
加:2022-03-21 21:02:21  更:2022-03-21 21:07:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 19:54:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码