iOS 拍照裁剪得到身份证照

实名认证功能在很多APP中都有,最近我们也加入了上传证件照功能,需要将裁剪后的身份证上传后台去校验,感觉也不难,我就使用了常用的类库对图片进行裁剪:

extension UIImage {
    func cropping(to rect: CGRect) -> UIImage{
            var rect = rect
            rect.origin.x *= self.scale
            rect.origin.y *= self.scale
            rect.size.width *= self.scale
            rect.size.height *= self.scale
            let imageRef = self.cgImage!.cropping(to: rect)
            let image = UIImage.init(cgImage: imageRef!)
            return image
    }
  }

咦,不是我想要的样子。为什么呢?后来发现拍照出来的照片并不是像素是3020*4030,并不是我们认为的屏幕大小相同的尺寸,所以即使根据屏幕比也得不到准确的位置。实际我使用iPhone 12拍摄得到这样尺寸的照片:


image.png

计算卡片所在位置

根据宽高比计算要截取身份证在图片中的位置:
卡片的宽高比:1150 / 1940 = 0.59
卡片和照片的宽度比:1940 / 3020 = 0.64
卡片Y轴位置比:750 / 4030 = 0.18

实现如下,具体要根据自己卡片所在位置计算

    func cropping(originImg: UIImage) -> UIImage? {
        let originSize = originImg.size
        let cardW = originSize.width * 0.64
        let cardH = cartW * 0.59
        let cardX = (originSize.width - cartW) / 2
        let cardY = originSize.height * 0.18
        let croppingRect = CGRect(x: cardX, y: cardY, width: cardW, height: cardH)
        
        guard let sourceImageRef = originImg.cgImage else { return nil }
        guard let newImageRef = sourceImageRef.cropping(to: croppingRect) else { return nil }
        let thumbImage = UIImage.init(cgImage: newImageRef)
        return thumbImage
    }

照片旋转问题

在这里还遇到一个问题就是拍照后的照片旋转问题,UIImage在UIImageView显示是没有问题的,但是在裁剪的时候得到的就是旋转的照片,这里直说解决方法

extension UIImage {
    func fixOrientation() -> UIImage{
        if self.imageOrientation == .up{
            return self
        }
        var transform = CGAffineTransform.identity
        
        switch self.imageOrientation {
        case .down, .downMirrored:
            transform = transform.translatedBy(x:self.size.width, y:self.size.height)
            transform = transform.rotated(by: .pi)
            break
            
        case .left, .leftMirrored:
            transform = transform.translatedBy(x:self.size.width, y:0)
            transform = transform.rotated(by: .pi/2)
            break
            
        case .right, .rightMirrored:
            transform = transform.translatedBy(x:0, y:self.size.height)
            transform = transform.rotated(by: -.pi/2)
            break
            
        default:
            break
        }
        
        switch self.imageOrientation {
        case .upMirrored, .downMirrored:
            transform = transform.translatedBy(x:self.size.width, y:0)
            transform = transform.scaledBy(x:-1, y:1)
            break
            
        case .leftMirrored, .rightMirrored:
            transform = transform.translatedBy(x:self.size.height, y:0);
            transform = transform.scaledBy(x:-1, y:1)
            break
        default:
            break
        }
        
        let ctx = CGContext(data:nil, width:Int(self.size.width), height:Int(self.size.height), bitsPerComponent:self.cgImage!.bitsPerComponent, bytesPerRow:0, space:self.cgImage!.colorSpace!, bitmapInfo:self.cgImage!.bitmapInfo.rawValue)
        ctx?.concatenate(transform)
        
        switch self.imageOrientation {
        case .left, .leftMirrored, .right, .rightMirrored:
            ctx?.draw(self.cgImage!, in:CGRect(x:CGFloat(0), y:CGFloat(0), width:CGFloat(size.height), height:CGFloat(size.width)))
            break
            
        default:
            ctx?.draw(self.cgImage!, in:CGRect(x:CGFloat(0), y:CGFloat(0), width:CGFloat(size.width), height:CGFloat(size.height)))
            break
        }
        
        let cgimg:CGImage = (ctx?.makeImage())!
        let img = UIImage(cgImage: cgimg)
        
        return img
    }
}

使用方式

let newImg = image.fixOrientation()
let thumbImage = cropping(originImg: newImg)

我是大自然的搬砖工,希望能够帮到你,谢谢~

参考:

iOS开发--解决拍照后照片旋转90度的问题(附Swift版本)

你可能感兴趣的:(iOS 拍照裁剪得到身份证照)