swift--Photo相关用法(图片压缩,拍照取色)

本示例包含

- 调用系统相机

- 读取系统相册图片

- 图片压缩

- 提取图片中某一点的颜色

- 把图片保存到系统相册

注意:

- 第一次运行会奔溃,根据日志中的提示在info.Plist文件中添加对应Key获取相关权限。

- 如果不压缩图片,选用相册中的高分辨率图片进行取色,在手指拖动时会有明显的卡顿


import UIKit
import Photos

class ViewController: UIViewController {
    
    let tagView = UIView()

    @IBOutlet weak var imageView: UIImageView!
    
    @IBAction func compressionClick(_ sender: Any) {
        if let image = imageView.image?.compression(size: CGSize(width: imageView.bounds.height, height: imageView.bounds.height)) {
            imageView.image = image
        }
    }
    
    @IBAction func saveImageClick(_ sender: Any) {
        if let image = imageView.image {
            UIImageWriteToSavedPhotosAlbum(image, self, #selector(saveImage(image:didFinishSavingWithError:contextInfo:)), nil)
        }
    }
    @objc func saveImage(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: AnyObject) {
        if error != nil{
            print("保存失败")
        }else{
            print("保存成功")
        }
    }
    
    //打开相机拍照
    @IBAction func tackPhotoClick(_ sender: Any) {
        if UIImagePickerController.isSourceTypeAvailable(.camera){
            let  cameraPicker = UIImagePickerController()
            cameraPicker.delegate = self
            cameraPicker.allowsEditing = true
            cameraPicker.sourceType = .camera
            //在需要的地方present出来
            self.present(cameraPicker, animated: true, completion: nil)
        } else {

           print("不支持拍照")

        }
    }
    
    //从相册选取照片
    @IBAction func selectPhotoClick(_ sender: Any) {
        let photoPicker =  UIImagePickerController()
        photoPicker.delegate = self
        photoPicker.allowsEditing = true
        photoPicker.sourceType = .photoLibrary
        //在需要的地方present出来
        self.present(photoPicker, animated: true, completion: nil)
    }
    
    override func viewDidLayoutSubviews() {
        tagView.frame = CGRect(x: imageView.center.x - 10, y: imageView.center.y - 10, width: 20, height: 20)
        tagView.backgroundColor = UIColor.clear
        tagView.layer.borderWidth = 2
        tagView.layer.borderColor = UIColor.red.cgColor
        self.view.addSubview(tagView)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let point = touch.location(in: imageView)
            self.view.backgroundColor = imageView.pickColor(at: point)
            self.tagView.frame = CGRect(x: point.x - 10, y: point.y - 10, width: 20, height: 20)
        }
    }
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let point = touch.location(in: imageView)
            self.view.backgroundColor = imageView.pickColor(at: point)
            self.tagView.frame = CGRect(x: point.x - 10, y: point.y - 10, width: 20, height: 20)
        }
    }
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        
    }

}

extension ViewController:UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        //用户取消了拍照或者选择照片
        print("用户取消了拍照")
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        print("获得照片============= \(info)")
        if let image : UIImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            //显示设置的照片
            self.imageView.image = image
        }
        self.dismiss(animated: true, completion: nil)
    }
}

extension UIImage {
     // 根据尺寸重新生成图片
     public func compression(size: CGSize) -> UIImage? {
         if self.size.height > size.height {
             let width = size.height / self.size.height * self.size.width
             let newImgSize = CGSize(width: width, height: size.height)
             UIGraphicsBeginImageContext(newImgSize)
             self.draw(in: CGRect(x: 0, y: 0, width: newImgSize.width, height: newImgSize.height))
             let theImage = UIGraphicsGetImageFromCurrentImageContext()
             UIGraphicsEndImageContext()
             guard let newImg = theImage else { return  nil}
             return newImg
         } else {
             let newImgSize = CGSize(width: size.width, height: size.height)
             UIGraphicsBeginImageContext(newImgSize)
             self.draw(in: CGRect(x: 0, y: 0, width: newImgSize.width, height: newImgSize.height))
             let theImage = UIGraphicsGetImageFromCurrentImageContext()
             UIGraphicsEndImageContext()
             guard let newImg = theImage else { return  nil}
             return newImg
         }
     }
    
}

extension UIView {
    
    // 获取特定位置的颜色
    public func pickColor(at position: CGPoint) -> UIColor? {
        
        // 用来存放目标像素值
        var pixel = [UInt8](repeatElement(0, count: 4))
        // 颜色空间为 RGB,这决定了输出颜色的编码是 RGB 还是其他(比如 YUV)
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        // 设置位图颜色分布为 RGBA
        let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue
        guard let context = CGContext(data: &pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: bitmapInfo) else {
            return nil
        }
        // 设置 context 原点偏移为目标位置所有坐标
        context.translateBy(x: -position.x, y: -position.y)
        // 将图像渲染到 context 中
        layer.render(in: context)
        
        return UIColor(red: CGFloat(pixel[0]) / 255.0,
                       green: CGFloat(pixel[1]) / 255.0,
                       blue: CGFloat(pixel[2]) / 255.0,
                       alpha: CGFloat(pixel[3]) / 255.0)
    }
    
    public func getPointRGB(at position: CGPoint) -> (Int32,Int32,Int32)? {
        // 用来存放目标像素值
        var pixel = [UInt8](repeatElement(0, count: 4))
        // 颜色空间为 RGB,这决定了输出颜色的编码是 RGB 还是其他(比如 YUV)
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        // 设置位图颜色分布为 RGBA
        let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue
        guard let context = CGContext(data: &pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: bitmapInfo) else {
            return nil
        }
        // 设置 context 原点偏移为目标位置所有坐标
        context.translateBy(x: -position.x, y: -position.y)
        // 将图像渲染到 context 中
        layer.render(in: context)
        let R:Int32 = Int32(pixel[0])
        let G:Int32 = Int32(pixel[1])
        let B:Int32 = Int32(pixel[2])
        
        return (R,G,B)
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_41735943/article/details/104653317