将图像从 Heic 转换为 Jpeg/Jpg

问题描述 投票:0回答:5

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

现在一切都工作得很好,直到iOS 10,但突然我们开始看到一些图片/图像无法显示,经过一些调试后我们发现这是由于苹果的新图像格式(HEIC)引起的问题,

我尝试改回本机 UIImagePicker(仅选取一张图像),并且图像显示为 Apple,我猜当用户选取它们时,会将图像从 HEIC 转换为 JPG,但当我使用第 3 方时,情况并非如此库,因为我需要实现多个图像选择器。

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

ios jpeg
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此网站


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。


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)
    }
}

0
投票

我已经这样做了,它对我有用。

第 1 步:从文件夹中选择图像,然后检查其扩展名

第 2 步:如果是 heic,则在将图像转换为 jpegdata 后,该数据将转换为图像。

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)
            }
        }}
© www.soinside.com 2019 - 2024. All rights reserved.