TIL

Image code - TIL

dion_K 2020. 12. 15. 22:26
728x90
class ImageViewController: UIViewController {
    
    @IBOutlet weak var imageView: UIImageView!
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let img1 = UIImage(named: "instagram")
        let img2 = #imageLiteral(resourceName: "instagram")
        
        imageView.image = img1 // 이미지 뷰에 이미지 표시
        
        // 이미지의 크기를 코드로 확인
        if let ptSize = img1?.size {
            print("Image Size: \(ptSize)")
        } // 픽셀이 아니라 포인트 단위로 리턴합니다.
        
        //만약 픽셀 단위의 크기를 얻고싶다면 사이즈 크기를 리턴한 값에 스케일 크기를 곱해야합니다.
        
        if let ptSize = img1?.size, let scale = img1?.scale {
            let px = CGSize(width: ptSize.width * scale, height: ptSize.height * scale)
            print("Image Size(px): \(px)")
        }
        // ?
        img1?.cgImage // UI이미지를 CG이미지로 바꾸는 코드
        img1?.ciImage // Ci 이미지로 바꾸는 코드
        
        // 이미지를 네트워크를 통해 다른 곳으로 전송하거나 파일에 저장하고 싶다면 바이너리 형태로 바꿔야합니다.
        let pngData = img1?.pngData()
        let jpgData = img1?.jpegData(compressionQuality: 1.0) // 1.0 을 전달하면 가장 높은 품질 
        
    }
}

< Resizeable & Vector >

class ResizableImageViewController: UIViewController {
    
    @IBOutlet weak var btn: UIButton!
    
    let btnImage = UIImage(named: "btn")
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        if let img = btnImage {
            let capInset = UIEdgeInsets(top: 14, left: 14, bottom: 14, right: 14)
            
            let bkgImage = img.resizableImage(withCapInsets: capInset, resizingMode: .tile)
            btn.setBackgroundImage(bkgImage, for: .normal)
        }
        
    }
}

< Template , Rendering> 

class RenderingModeViewController: UIViewController {
    
    @IBOutlet weak var imageView: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 원본 이미지 만들기, UIImage에는 withRenderingMode 메소드가 있습니다.
        if let img = UIImage(named: "pencil")?.withRenderingMode(.alwaysTemplate) {
            imageView.image = img
        }
    }
}

< Custom Drawing >

import UIKit

class CustomDrawingView: UIView {
    let starImg = UIImage(systemName: "star")
    let bellImg = UIImage(systemName: "bell")
    let umbrellaImg = UIImage(systemName: "umbrella")
    
    override func draw(_ rect: CGRect) {
        super.draw(rect)
        
        // 커스텀뷰를 구현할떄는 드로우 메소드를 오버라이딩 해서 그리기 코드를 직접 구현
        // UIImage가 제공하는 메소드를 사용해서 직접 구현하는 방법을 사용해야함
        
        starImg?.draw(at: CGPoint(x: 0, y: 0)) // 원하는 좌표의 이미지를 그리고 싶을때 사용 draw(at:)
        bellImg?.draw(in: CGRect(x: 0, y: 80, width: 100, height: 100)) // 크기를 함께 지정하고 싶다면 draw(in:) 메소드를 사용
        umbrellaImg?.drawAsPattern(in: rect) // 지정된 프레임의 이미지를 그리는데 이미지의 크기가 프레임보다 작다면 패턴 형태로 그림. drawAspattern
    }
}



class CustomImageDrawingViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
    }
}

< Resizing >

import UIKit
import CoreGraphics


class ImageResizingViewController: UIViewController {
    
    @IBOutlet weak var imageView: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 축소할 이미지와 축소할 크기를 선언
        if let targetImage = UIImage(named: "photo") {
            let size = CGSize(width: targetImage.size.width / 5, height: targetImage.size.height / 5)
            
//            imageView.image = resizingWithImageContext(image: targetImage, to: size)
            
            imageView.image = resizingWithBitmapContext(image: targetImage, to: size)
        }
        
    }
}




extension ImageResizingViewController {
    func resizingWithImageContext(image: UIImage, to size: CGSize) -> UIImage? {
//        UIGraphicsBeginImageContextWithOptions(<#T##size: CGSize##CGSize#>, <#T##opaque: Bool##Bool#>, <#T##scale: CGFloat##CGFloat#>) // 첫번째: 크기, 두번쨰: 이미지에 투명한 부분이 없다면 true, 있으면 false, 세번째: 이미지의 스케일 전달
        UIGraphicsBeginImageContextWithOptions(size, true, 0.0) // 이미지 컨택스트 생성, 쉽게말해 무언가를 그려줄 그림판을 만든다고 생각하면됨
        
        let frame = CGRect(origin: CGPoint.zero, size: size)
        image.draw(in: frame) // 이미지를 프레임 내부에 그림
        
        
        // 실제 이미지로 변경
        let resultImage = UIGraphicsGetImageFromCurrentImageContext() // 현재 사용중인 이미지 컨택스트에서 이미지를 가져오는 함수
        
        UIGraphicsEndImageContext() // 컨택스트에서 작업이 완료되면 반드시 컨택스를 해제해야함
        
        return resultImage
        
    }
} // 비교적 단순하게 구현할 수 있지만 context를 만들때 사용할 수 있는 옵션이 제한적임




// 비트 맵 context를 사용해서 구현
// import CoreGraphics를 사용해야함
extension ImageResizingViewController {
    func resizingWithBitmapContext(image: UIImage, to size: CGSize) -> UIImage? {
        
        // CoreCraphics 이미지로 변경해야함
        guard let cgImage = image.cgImage else {
            return nil
        }
        
        let bpc = cgImage.bitsPerComponent
        let bpr = cgImage.bytesPerRow
        let colorSpace = cgImage.colorSpace!
        let bitmapInfo = cgImage.bitmapInfo
        
        
        
        // 이어서 BitmapContext를 생성
        guard let context = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: bpc, bytesPerRow: bpr, space: colorSpace, bitmapInfo: bitmapInfo.rawValue) else {
            return nil
        }
        // 1: 랜더링할 메모리의 포인터를 전달해야 하는데 nil을 전달하면 자동으로 처리해줌 2: 넓이와 높이 3~: 원본 이지미의 속성을 그대로 전달
        
        
        // 이미지의 품질을 설정
        context.interpolationQuality = .high // 품질 저하를 최소화 시켜줌
        
        let frame = CGRect(origin: .zero, size: size)
        
        context.draw(cgImage, in: frame)
        
        // 컨텍스트에 그려진 이미지를 실제 이미지로 변경
        guard let resultImage = context.makeImage() else {
            return nil
        }
        
        
        
        // 마지막으로 cg이미지를 ui이미지로 바꿔서 리턴
        return UIImage(cgImage: resultImage)
        
    }
}



// iOS Image Resizing
// Swift Image Resizing
728x90