swift UIImage+

2020-04-03  本文已影响0人  梁间

//一些特定项目用到的UIImage+

import UIKit

extension UIImage
{
  //旋转 degrees
    func rotate(by degrees: CGFloat, flip: Bool? = nil) -> UIImage
    {
        let radians = CGFloat(degrees * (CGFloat.pi / 180.0))
        
        let bufferView = UIView(frame: CGRect(origin: CGPoint.zero, size: self.size))
        let t: CGAffineTransform = CGAffineTransform(rotationAngle: radians)
        bufferView.transform = t
        let bufferSize = bufferView.frame.size
        
        UIGraphicsBeginImageContextWithOptions(bufferSize, false, self.scale)
        let bitmap = UIGraphicsGetCurrentContext()
        bitmap?.translateBy(x: bufferSize.width / 2, y: bufferSize.height / 2)
        bitmap?.rotate(by: radians)
        if let isFlipped = flip {
            if !isFlipped {
                bitmap?.scaleBy(x: 1.0, y: -1.0)
            } else {
                bitmap?.scaleBy(x: -1.0, y: -1.0)
            }
        } else {
            bitmap?.scaleBy(x: -1.0, y: -1.0)
        }
        bitmap?.draw(self.cgImage!, in: CGRect(origin: CGPoint(x: -self.size.width / 2, y: -self.size.height / 2), size: self.size))
        
        let finalBuffer = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return finalBuffer!
    }

// MARK: - Init/Deinit functions
    convenience init?(imageBuffer: CVPixelBuffer) {
        var cgImage: CGImage?
        
        VTCreateCGImageFromCVPixelBuffer(imageBuffer, options: nil, imageOut: &cgImage)
        
        if let cgImage = cgImage {
            self.init(cgImage: cgImage)
        } else {
            return nil
        }
    }
    
    
    /// Resize image from given size.
    ///
    /// - Parameter newSize: Size of the image output.
    /// - Returns: Resized image.
    func resize(to newSize: CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(CGSize(width: newSize.width, height: newSize.height), true, 1.0)
        self.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
        let resizedImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        
        return resizedImage
    }
    
    func cutImage(rect:CGRect) ->UIImage{
        let cgimage = self.cgImage
        let newcgimage = cgimage?.cropping(to: rect)
        print(newcgimage?.width)
        let partuiimage = UIImage(cgImage: newcgimage!)
      
        UIGraphicsBeginImageContext(self.size)
        partuiimage.draw(in: rect)
        
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
    /// Crop image with given rectangle frame.
    ///
    /// - Parameter rect: Rectangle zone taken from the original image.
    /// - Returns: Cropped image.
    func crop(to rect: CGRect) -> UIImage {
        if let imageRef: CGImage = self.cgImage?.cropping(to: rect) {
            let cropped: UIImage = UIImage(cgImage: imageRef, scale: 0, orientation: self.imageOrientation)
            return cropped
        }
        return self
    }
    
    /// Square up the image and centerising the cropping.
    ///
    /// - Returns: Cropped image.
    func smartCrop() -> UIImage {
        var imageHeight = self.size.height
        var imageWidth = self.size.width
        
        if imageHeight > imageWidth {
            imageHeight = imageWidth
        }
        else {
            imageWidth = imageHeight
        }
        
        let size = CGSize(width: imageWidth, height: imageHeight)
        
        guard let width = self.cgImage?.width, let height = self.cgImage?.height else {
            return self
        }
        
        let refWidth: CGFloat = CGFloat(width)
        let refHeight: CGFloat = CGFloat(height)
        
        let x = (refWidth - size.width) / 2
        let y = (refHeight - size.height) / 2
        
        let cropRect = CGRect(x: x, y: y, width: size.height, height: size.width)
        return crop(to: cropRect)
    }
    
    
//图像buffer
    var buffer: CVPixelBuffer? {
        let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue] as CFDictionary
        var pixelBuffer: CVPixelBuffer?
        let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(self.size.width), Int(self.size.height), kCVPixelFormatType_32ARGB, attrs, &pixelBuffer)
        guard (status == kCVReturnSuccess) else {
            return nil
        }
        
        CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
        let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer!)
        
        let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
        let context = CGContext(data: pixelData, width: Int(self.size.width), height: Int(self.size.height), bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer!), space: rgbColorSpace, bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue)
        
        context?.translateBy(x: 0, y: self.size.height)
        context?.scaleBy(x: 1.0, y: -1.0)
        
        UIGraphicsPushContext(context!)
        self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        UIGraphicsPopContext()
        CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
        
        return pixelBuffer
    }
    //灰度图片转数组
    var greyData:[UInt8]{
        
        //var pixelValues: [UInt8]?
        
        let width = Int(self.size.width)
        let height = Int(self.size.height)
        let colorSpace =  self.cgImage?.colorSpace //CGColorSpaceCreateDeviceRGB()
        
        
        let bitsPerComponent = 8
        let bytesPerRow = width
        let totalBytes = height * width
        let bitmapInfo = CGImageAlphaInfo.none
        
        var intensities = [UInt8](repeating: 0, count: Int(totalBytes))
        
        let contextRef = CGContext(data: &intensities, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace!, bitmapInfo: bitmapInfo.rawValue)
    
        contextRef?.draw(self.cgImage!, in: CGRect(x: 0.0, y: 0.0, width: CGFloat(width), height: CGFloat(height)))

        return intensities
    
    }
 /** 
    Converts the image into an array of RGBA bytes.
   */
  @nonobjc public func toByteArray() -> [UInt8] {
    let width = Int(size.width)
    let height = Int(size.height)
    var bytes = [UInt8](repeating: 0, count: width * height * 4)

    bytes.withUnsafeMutableBytes { ptr in
      if let context = CGContext(
                    data: ptr.baseAddress,
                    width: width,
                    height: height,
                    bitsPerComponent: 8,
                    bytesPerRow: width * 4,
                    space: CGColorSpaceCreateDeviceRGB(),
                    bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) {

        if let image = self.cgImage {
          let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
          context.draw(image, in: rect)
        }
      }
    }
    return bytes
  }

  /**
    Creates a new UIImage from an array of RGBA bytes.
   */
  @nonobjc public class func fromByteArray(_ bytes: UnsafeMutableRawPointer,
                                           width: Int,
                                           height: Int) -> UIImage {

    if let context = CGContext(data: bytes, width: width, height: height,
                               bitsPerComponent: 8, bytesPerRow: width * 4,
                               space: CGColorSpaceCreateDeviceRGB(),
                               bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue),
       let cgImage = context.makeImage() {
      return UIImage(cgImage: cgImage, scale: 0, orientation: .up)
    } else {
      return UIImage()
    }
  }
//图片再特定点添加标记(十字)
    func addPoint(data:[Int]) -> UIImage {
        return addPoint(data: data, color: UIColor.red)
    }
    
    func addPoint(data:[Int], color:UIColor) -> UIImage {
    
    UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
   
    //传递1:将原始图像绘制为背景
    self.draw(at: CGPoint(x: 0, y: 0))

    
    //传递2:在原始图像上绘制线条
    let context = UIGraphicsGetCurrentContext()
    context?.setLineWidth(1.0)
    
    
    for i in 0..<data.count/2 {
        let x = data[2*i]
        let y = data[2*i+1]
        
        context?.move(to: CGPoint(x:x-5,y:y))
        context?.addLine(to: CGPoint(x:x+5,y:y))
        context?.move(to: CGPoint(x:x,y:y-5))
        context?.addLine(to: CGPoint(x:x,y:y+5))
    }
    //context?.move(to: CGPoint(x:10,y:10))
    //context?.addLine(to: CGPoint(x:100,y:100))
    context?.setStrokeColor(color.cgColor)

    context?.strokePath()
 
    
    //创建新图像
    var newImage = UIGraphicsGetImageFromCurrentImageContext()
    //收拾
    UIGraphicsEndImageContext()
    
    return newImage!
   }
   
//图片添加线
   func addLine(data1:[Int],data2:[Int]) -> UIImage {
      
      UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
     
      //传递1:将原始图像绘制为背景
      self.draw(at: CGPoint(x: 0, y: 0))

      
      //传递2:在原始图像上绘制线条
      let context = UIGraphicsGetCurrentContext()
      context?.setLineWidth(1.0)
      
      
      for i in 0..<data1.count/2 {
          let x1 = data1[2*i]
          let y1 = data1[2*i+1]
          let x2 = data2[2*i]
          let y2 = data2[2*i+1]
          
          context?.move(to: CGPoint(x:x1,y:y1))
          context?.addLine(to: CGPoint(x:x2,y:y2))
      }

      context?.setStrokeColor(UIColor.green.cgColor)

      context?.strokePath()
   
      
      //创建新图像
      var newImage = UIGraphicsGetImageFromCurrentImageContext()
      //收拾
      UIGraphicsEndImageContext()
      
      return newImage!
     }
    
    
     
}

上一篇下一篇

猜你喜欢

热点阅读