将HEIC格式的图像转换为JPEG/JPG

12

我有一个应用程序,用户可以上传多个图像,所有图像将存储在服务器上,并在我的iOS应用程序的Web视图上显示。

目前一切都很好,直到iOS 10之前,但突然间我们发现某些图片/图像无法显示,经过一番调试,我们发现这是由于苹果的新图像格式(HEIC)引起的问题,

我尝试改回本地的UIImagePicker(仅选择一张图像),发现当用户选择它们时,这些图像似乎由Apple转换成JPG格式,但是当我使用第三方库时情况并非如此,因为我需要实现多图像选择器。

尽管我们正在努力在服务器端进行转换以避免没有更新应用程序的用户遇到麻烦,但我也想看看是否有任何方法可以在我的应用程序中本地转换图像格式。

5个回答

15

上传照片到服务器之前,有一种解决方法可以将HEIC格式的照片转换为JPEG格式:

NSData *jpgImageData = UIImageJPEGRepresentation(image, 0.7);

如果您使用 PHAsset,想要获取图像对象,则需要从 PHImageManager 调用此方法:

- (PHImageRequestID)requestImageForAsset:(PHAsset *)asset targetSize:(CGSize)targetSize contentMode:(PHImageContentMode)contentMode options:(nullable PHImageRequestOptions *)options resultHandler:(void (^)(UIImage *__nullable result, NSDictionary *__nullable info))resultHandler;

在服务器端,您还可以直接使用该 API该网站


我实际上正在使用一个资产数组进行存储,有什么解决方案吗? - SriTeja Chilakamarri
你的意思是指 PHAsset 吗? - marshallino16
我更新了我的答案,你只需要循环遍历你的数组并调用这个requestImageForAsset方法。 - marshallino16
我正在尝试做类似的事情,这看起来是一个不错、简单的解决方案!然而,我不确定这里到底发生了什么。下面这行代码是什么意思?它应该放在哪里?“NSData *jpgImageData = UIImageJPEGRepresentation(image, 0.7);” 这行代码有哪些依赖关系? - Penjimon

6

我是这样做的:

     let newImageSize = Utility.getJpegData(imageData: imageData!, referenceUrl: referenceUrl!)

     /**
         - Convert heic image to jpeg format
     */
     public static func getJpegData(imageData: Data, referenceUrl: NSURL) -> Data {
         var newImageSize: Data?
         if (try? Data(contentsOf: referenceUrl as URL)) != nil
         {
                let image: UIImage = UIImage(data: imageData)!
                newImageSize = image.jpegData(compressionQuality: 1.0)
         }
            return newImageSize!
     }

2
在Swift 3中,假设有一个现有HEIF图片的输入路径和一个保存未来JPG文件的输出路径:
func fromHeicToJpg(heicPath: String, jpgPath: String) -> UIImage? {
        let heicImage = UIImage(named:heicPath)
        let jpgImageData = UIImageJPEGRepresentation(heicImage!, 1.0)
        FileManager.default.createFile(atPath: jpgPath, contents: jpgImageData, attributes: nil)
        let jpgImage = UIImage(named: jpgPath)
        return jpgImage
    }

它会返回jpgPath的UIImage,如果出现问题则返回null。

1
我已经按照这种方式做了,对我来说有效。
步骤1:从文件夹中选择图像,然后检查其扩展名。
步骤2:如果是heic格式,则将该数据转换为图像,然后将图像转换为jpeg数据。
func getJpegData(imageData: Data) -> Data? {
         var newImageSize: Data?
     guard imageData.count != 0 else {
         return nil
     }
    let image: UIImage = UIImage(data: imageData)!
      newImageSize = image.jpegData(compressionQuality:0.6)
     return newImageSize!

     }

步骤3:然后在将带有扩展名的文件名发送到服务器之前,将该文件扩展名更改为jpeg。
let fName = filename.replacingOccurrences(of: "heic", with: "jpeg")

最终调用的代码为:
func attachmentPickerMenu(_ menu: HSAttachmentPicker, upload data: Data, filename: String, image: UIImage?) {
      
        let fm = FileManager.default
        let docsurl = try! fm.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
        let myurl = docsurl.appendingPathComponent(filename)
        let mtype = myurl.mimeType()
        let imgExtensons = myurl.pathExtension
        print("mtype:",mtype,"myurl:",myurl, "docsurl:",docsurl,"imgExtensins:",imgExtensons, "filenamess:",filename)
        
        if imgExtensons.lowercased() == "heic" {
           
            let imgData = CEnumClass.share.getJpegData(imageData: data)
            guard  imgData != nil  else{
                return self.view.makeToast(ConstantStr.somethingWorng.val, duration: 2, position: .center)
            }
            let fName = filename.replacingOccurrences(of: "heic", with: "jpeg")
            DispatchQueue.main.async {
                self.pendingDocViewModel.uploadAddReimburseData(serviceFormData: imgData!, mimeTpes: "image/jpeg", fileName: fName)
            }
        }}

0

我发现现有的答案很有帮助,但我决定也分享我的解决方案。希望它更加清晰和“完整”。

这个解决方案将图片保存到文件中。

private let fileManager: FileManager

func save(asset: PHAsset, to destination: URL) {
    let options = PHContentEditingInputRequestOptions()
    options.isNetworkAccessAllowed = true

    asset.requestContentEditingInput(with: options) { input, info in
        guard let input = input, let url = input.fullSizeImageURL else {
            return // you might want to handle this case
        }

        do {
            try self.save(input, at: url, to: destination)
            // success!
        } catch {
            // failure, handle the error!
        }
    }
}

private func copy(
    _ input: PHContentEditingInput, at url: URL, to destination: URL
) throws {
    let uniformType = input.uniformTypeIdentifier ?? ""
    switch uniformType {
    case UTType.jpeg.identifier:
        // Copy JPEG files directly
        try fileManager.copyItem(at: url, to: destination)
    default:
        // Convert HEIC/PNG and other formats to JPEG and save to file
        let image = UIImage(data: try Data(contentsOf: url))
        guard let data = image?.jpegData(compressionQuality: 1) else {
            return // you might want to handle this case
        }
        try data.write(to: destination)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接