UIImage를 NSData로 변환하고 Swift에서 UIImage로 다시 변환 하시겠습니까?


143

나는를 저장하기 위해 노력하고있어 UIImageNSData다음 읽을 NSData새로운 다시 UIImage스위프트에 있습니다. 을 변환하려면 UIImageNSData나는 다음과 같은 코드를 사용하고 있습니다 :

let imageData: NSData = UIImagePNGRepresentation(myImage)

어떻게 변환합니까 imageData(즉, NSData새로운에) 다시 UIImage?

답변:


155

UIImage(data:imageData,scale:1.0) 이미지의 스케일이 1이라고 가정합니다.

신속한 4.2에서는 아래 코드를 사용하여 Data ()를 가져옵니다.

image.pngData()

67

감사. 많은 도움이되었습니다. 스위프트 3으로 변환하여 작업

저장하려면 : let data = UIImagePNGRepresentation(image)

로드하려면 let image = UIImage(data: data)


1
하지가 let imagePt = UIImage(data: caminhodaImagem)충분?
superarts.org


17

이제 Swift 4.2 에서는 pngData()새로운 인스턴스 메소드를 사용 UIImage하여 이미지에서 데이터를 가져올 수 있습니다.

let profileImage = UIImage(named:"profile")!
let imageData = profileImage.pngData()

Swift 4.2는 베타 버전입니까? 이 기능을 사용할 수 없습니다
Daniel Springer

이름이 바뀐 것 같습니다
吖 奇 说-何魏奇 Archy Will He

'pngData ()'가 'UIImagePNGRepresentation (_ :)'으로 이름이 바뀌 었습니다.
j2abro

9

세부

  • Xcode 10.2.1 (10E1001), 스위프트 5

해결책 1

guard let image = UIImage(named: "img") else { return }
let jpegData = image.jpegData(compressionQuality: 1.0)
let pngData = image.pngData()

솔루션 2.1

extension UIImage {
    func toData (options: NSDictionary, type: CFString) -> Data? {
        guard let cgImage = cgImage else { return nil }
        return autoreleasepool { () -> Data? in
            let data = NSMutableData()
            guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else { return nil }
            CGImageDestinationAddImage(imageDestination, cgImage, options)
            CGImageDestinationFinalize(imageDestination)
            return data as Data
        }
    }
}

솔루션 사용법 2.1

// about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
let options: NSDictionary =     [
    kCGImagePropertyOrientation: 6,
    kCGImagePropertyHasAlpha: true,
    kCGImageDestinationLossyCompressionQuality: 0.5
]

// https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
guard let data = image.toData(options: options, type: kUTTypeJPEG) else { return }
let size = CGFloat(data.count)/1000.0/1024.0
print("\(size) mb")

솔루션 2.2

extension UIImage {

    func toJpegData (compressionQuality: CGFloat, hasAlpha: Bool = true, orientation: Int = 6) -> Data? {
        guard cgImage != nil else { return nil }
        let options: NSDictionary =     [
                                            kCGImagePropertyOrientation: orientation,
                                            kCGImagePropertyHasAlpha: hasAlpha,
                                            kCGImageDestinationLossyCompressionQuality: compressionQuality
                                        ]
        return toData(options: options, type: .jpeg)
    }

    func toData (options: NSDictionary, type: ImageType) -> Data? {
        guard cgImage != nil else { return nil }
        return toData(options: options, type: type.value)
    }
    // about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
    func toData (options: NSDictionary, type: CFString) -> Data? {
        guard let cgImage = cgImage else { return nil }
        return autoreleasepool { () -> Data? in
            let data = NSMutableData()
            guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else { return nil }
            CGImageDestinationAddImage(imageDestination, cgImage, options)
            CGImageDestinationFinalize(imageDestination)
            return data as Data
        }
    }

    // https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
    enum ImageType {
        case image // abstract image data
        case jpeg                       // JPEG image
        case jpeg2000                   // JPEG-2000 image
        case tiff                       // TIFF image
        case pict                       // Quickdraw PICT format
        case gif                        // GIF image
        case png                        // PNG image
        case quickTimeImage             // QuickTime image format (OSType 'qtif')
        case appleICNS                  // Apple icon data
        case bmp                        // Windows bitmap
        case ico                        // Windows icon data
        case rawImage                   // base type for raw image data (.raw)
        case scalableVectorGraphics     // SVG image
        case livePhoto                  // Live Photo

        var value: CFString {
            switch self {
            case .image: return kUTTypeImage
            case .jpeg: return kUTTypeJPEG
            case .jpeg2000: return kUTTypeJPEG2000
            case .tiff: return kUTTypeTIFF
            case .pict: return kUTTypePICT
            case .gif: return kUTTypeGIF
            case .png: return kUTTypePNG
            case .quickTimeImage: return kUTTypeQuickTimeImage
            case .appleICNS: return kUTTypeAppleICNS
            case .bmp: return kUTTypeBMP
            case .ico: return kUTTypeICO
            case .rawImage: return kUTTypeRawImage
            case .scalableVectorGraphics: return kUTTypeScalableVectorGraphics
            case .livePhoto: return kUTTypeLivePhoto
            }
        }
    }
}

솔루션 사용법 2.2

let compressionQuality: CGFloat = 0.4
guard let data = image.toJpegData(compressionQuality: compressionQuality) else { return }
printSize(of: data)

let options: NSDictionary =     [
                                    kCGImagePropertyHasAlpha: true,
                                    kCGImageDestinationLossyCompressionQuality: compressionQuality
                                ]
guard let data2 = image.toData(options: options, type: .png) else { return }
printSize(of: data2)

문제

이미지를 나타내는 데는 많은 CPU 및 메모리 리소스가 필요합니다. 따라서이 경우 몇 가지 규칙을 따르는 것이 좋습니다.

-메인 큐에서 jpegData (compressionQuality :)를 실행하지 마십시오

-하나의 jpegData (compressionQuality :) 만 동시에 실행

잘못된:

for i in 0...50 {
    DispatchQueue.global(qos: .utility).async {
        let quality = 0.02 * CGFloat(i)
        //let data = image.toJpegData(compressionQuality: quality)
        let data = image.jpegData(compressionQuality: quality)
        let size = CGFloat(data!.count)/1000.0/1024.0
        print("\(i), quality: \(quality), \(size.rounded()) mb")
    }
}

권리:

let serialQueue = DispatchQueue(label: "queue", qos: .utility, attributes: [], autoreleaseFrequency: .workItem, target: nil)

for i in 0...50 {
    serialQueue.async {
        let quality = 0.02 * CGFloat(i)
        //let data = image.toJpegData(compressionQuality: quality)
        let data = image.jpegData(compressionQuality: quality)
        let size = CGFloat(data!.count)/1000.0/1024.0
        print("\(i), quality: \(quality), \(size.rounded()) mb")
    }
}

연결


사실 이것은 매우 도움이되었습니다. 코드를 사용하여 UIImage를 bmps로 변환 할 수 있습니다. 또한 bmp에서 알파를 제거해야합니다. 알파를 제거하는 옵션을 설정하려고했지만 레이어를 제거하지 못하는 것 같습니다. 다음과 같이 전화를 겁니다 : let 옵션 : NSDictionary = [kCGImagePropertyHasAlpha : false] let convertToBmp = image.toData (options : options, type : .bmp)
Gallaugher

@ Gallaugher 작동하지 않습니까? 알파가없는 png 이미지를 만들어 확인하십시오. kCGImagePropertyHasAlpha 특성을 bmp와 함께 사용하는 것이 불가능할 수 있습니다.
Vasily Bodnarchuk

@ vasily-bodnarchuk 리드 (및 이전 코드)에 감사드립니다. 알파를 제거했습니다-png를 통해 할 수 없었지만 resizedImage.toJpegData를 알파로 false로 사용한 다음이 데이터를 다시 UIImage로 변환 한 다음 .bmp 유형의 toData를 수행했습니다. 옵션은 영향을 미치지 않았지만 Photoshop에서 알파 레이어가 제거되어 더 작은 파일이 만들어졌습니다. 여전히 PyPortal에 필요한 정확한 16 비트 래스터 그래픽 bmp 형식을 생성 할 수 없습니다. 어떤 이유로 온라인 변환과 같은 도구를 통해 변환하면 관심있는 데이터가 표시되지 않습니다. 고마워.
Gallaugher

@ vasily-bodnarchuk, 유용한 코드를 사용하여 저장 한 bmp는 Photoshop에서 bmp 옵션 "Flip row order"가 열립니다. "다른 이름으로 저장 ..."다음에 나타나는 "BMP 옵션"화면에서이 옵션을 다시 저장하고 선택 취소하면 PyPortal에 bmp를로드하면 업데이트 된 bmp가 표시됩니다. "Flip row order"옵션처럼 보이는 Apple 문서는 보이지 않습니다. 왜 이것이 기본 저장으로 표시되는지 잘 모르겠으며 Swift에서 이것을 "실행 취소"하는 방법을 잘 모르겠습니다. BTW : Q & 관련 파일을 stackoverflow.com/questions/57241391/에 게시했습니다. 감사합니다!
Gallaugher

8

데이터로 저장하려면

StoryBoard에서 MainStoryBoard의 imageView에 "이미지"데이터를 저장하려는 경우 다음 코드가 작동합니다.

let image = UIImagePNGRepresentation(imageView.image!) as NSData?

imageView에 "image"를로드하려면 느낌표 "!", "?"를보십시오. 이것이 이것과 상당히 같은지 여부

imageView.image = UIImage(data: image as! Data)

이 과정에서 "NSData"유형이 "Data"유형으로 자동 변환됩니다.


6

코드의 안전한 실행 을 위해 함수 가 선택적 값을 반환하므로 if-letblock with Data를 사용 하여 앱 충돌 및를 방지하십시오 UIImagePNGRepresentation.

if let img = UIImage(named: "TestImage.png") {
    if let data:Data = UIImagePNGRepresentation(img) {
       // Handle operations with data here...         
    }
}

참고 : 데이터 는 Swift 3+ 클래스입니다. Swift 3+에서 NSData 대신 Data 사용

일반 이미지 작업 (예 : png 및 jpg 모두) :

if let img = UIImage(named: "TestImage.png") {  //UIImage(named: "TestImage.jpg")
        if let data:Data = UIImagePNGRepresentation(img) {
               handleOperationWithData(data: data)     
        } else if let data:Data = UIImageJPEGRepresentation(img, 1.0) {
               handleOperationWithData(data: data)     
        }
}

*******
func handleOperationWithData(data: Data) {
     // Handle operations with data here...
     if let image = UIImage(data: data) {
        // Use image...
     }
}

확장을 사용하여 :

extension UIImage {

    var pngRepresentationData: Data? {
        return UIImagePNGRepresentation(self)
    }

    var jpegRepresentationData: Data? {
        return UIImageJPEGRepresentation(self, 1.0)
    }
}

*******
if let img = UIImage(named: "TestImage.png") {  //UIImage(named: "TestImage.jpg")
      if let data = img.pngRepresentationData {
              handleOperationWithData(data: data)     
      } else if let data = img.jpegRepresentationData {
              handleOperationWithData(data: data)     
     }
}

*******
func handleOperationWithData(data: Data) {
     // Handle operations with data here...
     if let image = UIImage(data: data) {
        // Use image...
     }
}

4

이미지 데이터 :-

    if let img = UIImage(named: "xxx.png") {
        let pngdata = img.pngData()
    }

   if let img = UIImage(named: "xxx.jpeg") {
        let jpegdata = img.jpegData(compressionQuality: 1)
    }

데이터를 이미지로 :-

 let image = UIImage(data: pngData)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.