CIFilter

作者: iOSWater | 来源:发表于2020-09-07 19:11 被阅读0次

基础用法
对一张图使用一个滤镜效果,总结起来需要四步:

1.创建一个CIImage对象 .CImage 有很多初始化方法。譬如:CIImage(contentsOfURL:), CIImage(data:), CIImage(CGImage:), CIImage(bitmapData:bytesPerRow:size:format:colorSpace:),用的最多的是CIImage(contentsOfURL:)。
2.创建一个CIContext. CIContext 可能是基于CPU,也可能是基于GPU的。所以创建CIContext会消耗资源,影响性能,我们应该尽可能多的复用它。将处理过后的图片数据,输出为CIImage的时候会用到CIContext。
3.创建一个滤镜. 创建好滤镜后,我们需要为其设置参数。有的滤镜要设置的参数比较多,有的滤镜却不需要设置参数。
4.获取filter output. 滤镜会输出一个CIImage对象,用CIContext 可以将CIImage转换为UIImage。

// 1.获取本地图片路径
let fileURL = NSBundle.mainBundle().URLForResource("image", withExtension: "png") 
// 2.创建CIImage对象
let beginImage = CIImage(contentsOfURL: fileURL!) 
// 3. 创建滤镜
// 创建一个棕榈色滤镜
let filter = CIFilter(name: "CISepiaTone")!
filter.setValue(beginImage, forKey: kCIInputImageKey)
// 设置输入的强度系数
filter.setValue(0.5, forKey: kCIInputIntensityKey)
// 4.将CIImage转换为UIImage 
//  其实在这个API内部用到了CIContext,而它就是在每次使用的使用去创建一个新的CIContext,比较影响性能
let newImage = UIImage(CIImage: filter.outputImage!)
self.imageView.image = newImage

import Foundation
import UIKit
import Kingfisher

class ImageViewUtil {
    class func createQRForString(qrString: String?, qrImageName: String?) -> UIImage?{
        if let sureQRString = qrString{
            let stringData = sureQRString.data(using: String.Encoding.utf8, allowLossyConversion: false)
            //创建一个二维码的滤镜
            let qrFilter = CIFilter(name: "CIQRCodeGenerator")
            qrFilter?.setValue(stringData, forKey: "inputMessage")
            qrFilter?.setValue("H", forKey: "inputCorrectionLevel")
            let qrCIImage = qrFilter?.outputImage
            
            // 创建一个颜色滤镜,黑白色
            let colorFilter = CIFilter(name: "CIFalseColor")!
            colorFilter.setDefaults()
            colorFilter.setValue(qrCIImage, forKey: "inputImage")
            colorFilter.setValue(CIColor(red: 0, green: 0, blue: 0), forKey: "inputColor0")
            colorFilter.setValue(CIColor(red: 1, green: 1, blue: 1), forKey: "inputColor1")
            // 返回二维码image
            let codeImage = UIImage(ciImage: (colorFilter.outputImage!.transformed(by: CGAffineTransform(scaleX: 5, y: 5))))
            
            // 中间一般放logo
            if let iconImage = UIImage(named: qrImageName!) {
                let rect = CGRect(x: 0, y: 0, width: codeImage.size.width, height: codeImage.size.height)
                
                UIGraphicsBeginImageContext(rect.size)
                codeImage.draw(in: rect)
                let avatarSize = CGSize(width: rect.size.width*0.25, height: rect.size.height*0.25)
                
                let x = (rect.width - avatarSize.width) * 0.5
                let y = (rect.height - avatarSize.height) * 0.5
                iconImage.draw(in: CGRect(x: x, y: y, width: avatarSize.width, height: avatarSize.height))
                
                let resultImage = UIGraphicsGetImageFromCurrentImageContext()
                
                UIGraphicsEndImageContext()
                return resultImage
            }
            return codeImage
        }
        return nil
    }
    
    //MARK: Abner 新版方法 根据传进去字符串,生成二维码图片
    class func theSecondSetupQRCodeImage(_ text: String, image: UIImage?) -> UIImage {
        //创建滤镜
        let filter = CIFilter(name: "CIQRCodeGenerator")
        filter?.setDefaults()
        //将url加入二维码
        filter?.setValue(text.data(using: String.Encoding.utf8), forKey: "inputMessage")
        //取出生成的二维码(不清晰)
        if let outputImage = filter?.outputImage {
            //生成清晰度更好的二维码
            let qrCodeImage = setupHighDefinitionUIImage(outputImage, size: 300)
            return qrCodeImage
        }
        return UIImage()
    }
    
    //MARK: -传进去字符串,生成二维码图片
    class func setupQRCodeImage(_ text: String, image: UIImage?) -> UIImage {
        //创建滤镜
        let filter = CIFilter(name: "CIQRCodeGenerator")
        filter?.setDefaults()
        //将url加入二维码
        filter?.setValue(text.data(using: String.Encoding.utf8), forKey: "inputMessage")
        //取出生成的二维码(不清晰)
        if let outputImage = filter?.outputImage {
            //生成清晰度更好的二维码
            let qrCodeImage = setupHighDefinitionUIImage(outputImage, size: 300)
            //如果有一个头像的话,将头像加入二维码中心
            if let image = image {
                //给头像加一个白色圆边(如果没有这个需求直接忽略)
//                image = circleImageWithImage(image, borderWidth: 50, borderColor: UIColor.white)
                //合成图片
                let newImage = syntheticImage(qrCodeImage, iconImage: image, width: 75, height: 75)
                
                return newImage
            }
            
            return qrCodeImage
        }
        
        return UIImage()
    }
    
    //image: 二维码 iconImage:头像图片 width: 头像的宽 height: 头像的宽
    private class func syntheticImage(_ image: UIImage, iconImage:UIImage, width: CGFloat, height: CGFloat) -> UIImage{
        //开启图片上下文
        UIGraphicsBeginImageContext(image.size)
        //绘制背景图片
        image.draw(in: CGRect(origin: CGPoint.zero, size: image.size))
        
        let x = (image.size.width - width) * 0.5
        let y = (image.size.height - height) * 0.5
        iconImage.draw(in: CGRect(x: x, y: y, width: width, height: height))
        //取出绘制好的图片
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        //关闭上下文
        UIGraphicsEndImageContext()
        //返回合成好的图片
        if let newImage = newImage {
            return newImage
        }
        return UIImage()
    }
    
    //MARK: - 生成高清的UIImage
    private class func setupHighDefinitionUIImage(_ image: CIImage, size: CGFloat) -> UIImage {
        let integral: CGRect = image.extent.integral
        let proportion: CGFloat = min(size/integral.width, size/integral.height)
        
        let width = integral.width * proportion
        let height = integral.height * proportion
        let colorSpace: CGColorSpace = CGColorSpaceCreateDeviceGray()
        let bitmapRef = CGContext(data: nil, width: Int(width), height: Int(height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: 0)!
        
        let context = CIContext(options: nil)
        let bitmapImage: CGImage = context.createCGImage(image, from: integral)!
        
        bitmapRef.interpolationQuality = CGInterpolationQuality.none
        bitmapRef.scaleBy(x: proportion, y: proportion);
        bitmapRef.draw(bitmapImage, in: integral);
        let image: CGImage = bitmapRef.makeImage()!
        return UIImage(cgImage: image)
    }
    
    //生成边框
    private class func circleImageWithImage(_ sourceImage: UIImage, borderWidth: CGFloat, borderColor: UIColor) -> UIImage {
        let imageWidth = sourceImage.size.width + 2 * borderWidth
        let imageHeight = sourceImage.size.height + 2 * borderWidth
        
        UIGraphicsBeginImageContextWithOptions(CGSize(width: imageWidth, height: imageHeight), false, 0.0)
        UIGraphicsGetCurrentContext()
        
        let radius = (sourceImage.size.width < sourceImage.size.height ? sourceImage.size.width:sourceImage.size.height) * 0.5
        let bezierPath = UIBezierPath(arcCenter: CGPoint(x: imageWidth * 0.5, y: imageHeight * 0.5), radius: radius, startAngle: 0, endAngle: .pi * 2, clockwise: true)
        bezierPath.lineWidth = borderWidth
        borderColor.setStroke()
        bezierPath.stroke()
        bezierPath.addClip()
        sourceImage.draw(in: CGRect(x: borderWidth, y: borderWidth, width: sourceImage.size.width, height: sourceImage.size.height))
        
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return image!
    }
    
    class func saveImage(currentImage: UIImage, newSize: CGSize, imageName: String){
        //压缩图片尺寸
        UIGraphicsBeginImageContext(newSize)
        currentImage.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
        if let newImage = UIGraphicsGetImageFromCurrentImageContext() {
            //UIImageJPEGRepresentation此方法可将图片压缩,但是图片质量基本不变,第二个参数即图片质量参数。
            if let imageData = UIImageJPEGRepresentation(newImage, 1) as NSData? {
                let fullPath = NSHomeDirectory().appending("/Documents/").appending(imageName)
                imageData.write(toFile: fullPath, atomically: true)
                DLog("fullPath=\(fullPath)")
            }
        }
    }
    
    class func resetImgSize(sourceImage : UIImage,maxImageLenght : CGFloat,maxSizeKB : CGFloat) -> String {
        
        var maxSize = maxSizeKB
        
        var maxImageSize = maxImageLenght
        
        
        
        if (maxSize <= 0.0) {
            
            maxSize = 1024.0;
            
        }
        
        if (maxImageSize <= 0.0)  {
            
            maxImageSize = 1024.0;
            
        }
        
        //先调整分辨率
        
        var newSize = CGSize.init(width: sourceImage.size.width, height: sourceImage.size.height)
        
        let tempHeight = newSize.height / maxImageSize;
        
        let tempWidth = newSize.width / maxImageSize;
        
        if (tempWidth > 1.0 && tempWidth > tempHeight) {
            
            newSize = CGSize.init(width: sourceImage.size.width / tempWidth, height: sourceImage.size.height / tempWidth)
            
        }
            
        else if (tempHeight > 1.0 && tempWidth < tempHeight){
            
            newSize = CGSize.init(width: sourceImage.size.width / tempHeight, height: sourceImage.size.height / tempHeight)
            
        }
        
        UIGraphicsBeginImageContext(newSize)
        
        sourceImage.draw(in: CGRect.init(x: 0, y: 0, width: newSize.width, height: newSize.height))
        
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        
        UIGraphicsEndImageContext()
        
        var imageData = UIImageJPEGRepresentation(newImage!, 1.0)
        
        var sizeOriginKB : CGFloat = CGFloat((imageData?.count)!) / 1024.0;
        
        //调整大小
        
        var resizeRate = 0.9;
        
        while (sizeOriginKB > maxSize && resizeRate > 0.1) {
            
            imageData = UIImageJPEGRepresentation(newImage!,CGFloat(resizeRate));
            
            sizeOriginKB = CGFloat((imageData?.count)!) / 1024.0;
            
            resizeRate -= 0.1;
            
        }
        let base64String = imageData!.base64EncodedString()
        return  base64String
        
    }
    
    class func getImage(named : String) -> UIImage?{
        let image = UIImage(contentsOfFile: NSHomeDirectory().appending("/Documents/").appending(named))
        return image
    }
    
    class func imageIsExist(named : String) -> Bool{
        let file = FileManager.default
        let filePath = NSHomeDirectory().appending("/Documents/").appending(named)
        return file.fileExists(atPath:filePath)
    }
class func getImagePath(named : String) -> String{
        return NSHomeDirectory().appending("/Documents/").appending(named)
    }
    
    ///传入图片image回传对应的base64字符串,默认不带有data标识,
    class func imageToBase64String(image:UIImage,headerSign:Bool = false)->String?{
        
        ///根据图片得到对应的二进制编码
        guard let imageData = UIImagePNGRepresentation(image) else {
            return nil
        }
        ///根据二进制编码得到对应的base64字符串
        var base64String = imageData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue:0))
        ///判断是否带有头部base64标识信息
        if headerSign {
            ///根据格式拼接数据头 添加header信息,扩展名信息
            base64String = "data:image/png;base64," + base64String
        }
        return base64String
    }
    
    
    
    class func downImageYZ(imageView : UIImageView){
        
        
        let host = CallUtil.serverUrl;
        let path = CallUtil.imageYZUrl;
        let method = "POST";
        let querys = "";
        let url = host+path+querys
        DLog(url)
        var postData : Data!
        let dic : NSMutableDictionary = [:]
        do {
            postData = try JSONSerialization.data(withJSONObject: dic, options: JSONSerialization.WritingOptions.prettyPrinted)
        }catch let err {
            DLog(err.localizedDescription)
            postData = Data()
        }
        let request = NSMutableURLRequest(url: URL(string: url)!, cachePolicy: NSURLRequest.CachePolicy(rawValue: 1)!, timeoutInterval: 5)
        request.httpMethod  =  method;
        request.addValue(GlobalArea.share.token ?? "", forHTTPHeaderField: "token")
        request.addValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")
        request.httpBody = postData
        let requestSession = URLSession(configuration: URLSessionConfiguration.default)
        let reques = request as URLRequest
        let task = requestSession.dataTask(with: reques) { (body, respons, erre) in
            if(body != nil){
               
                let image = UIImage(data: body!)
                DispatchQueue.main.async {
                    imageView.image = image
                }
            }
            
            if(erre != nil){
                DLog(erre.debugDescription)
            }
        }
        task.resume()
    }
    
    
   
    
    
}

相关文章

网友评论

      本文标题:CIFilter

      本文链接:https://www.haomeiwen.com/subject/hovlektx.html