HEIC 图画紧缩

JPEG IFF 格局通常或许的格局。JPEG 格局文件类型或许是JPEG 格局的文件。

HEIF 或多种图画文件格局,在许多方面都将是一种 JPEG 前身。格局由 2013 年,称号类型能够代替它的格局,支撑 JPEG 的数据的图画数据,包括:

  • 项目
  • 顺序
  • 推导
  • 元数据
  • 辅佐图画项

这些数据类型 HEIF 能够比 JPEG存储最新的最新数据更多。这个图画修改图画运用)示例(例如存储的十分有用。您还能够存储 iPhone 上记载的)

MPEG 规范中界说了扩展名。关于他们的 HEIF 文件,Apple 决定运用**.ic**扩展名,它由多种图画容器代表。他们的挑选代表设备运用 HEVC 解码器的文件,但 Apple 也能够读取其他文件一些编解码器紧缩的文件。

入门

要开端运用,请您收藏本教程顶部或下载的材料按钮。在 zip 文件中,找到两个文件夹的FinalStarter

这是一个简单的示例运用程序,显现两个图画视图和一个用于调整图片的 JPEG 和他的图片展现项目的标签。 ,一切这些都形成了一个无功用的功用。

此运用程序的方针是通过显现图画紧缩所需的时刻以及 HEIC 文件的巨细来展现运用 HEIC 与 JPEG 的优势。它还展现了如何运用同享表同享 HEIC 文件。

另存为HEIC

打开发动项目后,并运转以检查运用程序的 UI 运转状况。

适用于 iOS 的 HEIC 图像压缩

在开端紧缩图画之前,您需求挑选图画。Jeremy Thomas在 Unsplash上的默认图片很不错,但最好看看它是如何在您自己的内容上工作的。

在MainViewController.swift中,将以下内容增加究竟部文件:

扩展MainViewController : UIImagePickerControllerDelegate ,
                               UINavigationControllerDelegate {
   func  imagePickerControllerDidCancel ( _picker : UIImagePickerController ) {
     // 1
    picker.dismiss(动画:真)
  }
  功用图画挑选控制器(
    _挑选器:UIImagePickerController,
    didFinishPickingMediaWithInfo
    信息:[ UIImagePickerController . InfoKey:任意]
    ) {
    picker.dismiss(动画:真)
    // 2
    护卫让 image = info[.originalImage] as?  UIImage其他{
      回来
    }
    // 3
    原始图画=图画
    更新图画()
  }
}

这是一个简单的完结UIImagePickerControllerDelegate。你在这里:

  1. 单击撤销按钮时封闭挑选器。
  2. 从挑选器中获取原始图画,以便在此运用中取得最佳效果。
  3. 存储此图画并更新图画视图。

现在updateImages()什么都不做。接下来,将这些行增加到空addButtonPressed()

让挑选器=  UIImagePickerController ()
picker.delegate =  self
礼物(挑选器,动画:真)

这是一个图画才干挑选器,让用户能够自己挑选。可是,您仍然需求更新图画才干正常工作。

compressJPGImage(with:)用以下内容替换和空完结compressHEICImage(with:)

private  func  compressJPGImage(质量:CGFloat) {
  jpgImageView.image = originalImage
}
个人功用紧缩HEICImage(质量:CGFloat) {
  heicImageView.image = originalImage
}

图画视图将显现挑选的图画。两个图画现在是暂时的,但将验证是否正常工作。

现在,并运转运用程序。挑选一个图画以检查它是否呈现在两个图画视图中。

适用于 iOS 的 HEIC 图像压缩

模仿出来之后就能够运用显现器了。但它还没有做任何后续的图画显现类型的强度调整。

在上显现此问题时,您需求在设备上显现更多类似的问题。

首先在MainViewController.swift的顶部增加以下内容originalImage

var previousQuality : Float  =  0

将存储一个最常见的特点,因而您将运用它来根据这个特点的更新次数。

,在 MainViewController 部分的下面增加两个办法:

@objc私有函数调用(){
  更新图画()
}
@objc私有特点IDChange () {
  让 diff =  abs (compressionSlider.value - previousQuality)
  护卫差异>  0.1不然{
    回来
  }
  previousQuality = compressionSlider.value
  更新图画()
}

这个办法的每日更新次数是最新的。

在底部viewDidLoad()增加以下内容:

紧缩方针.addTarget(
  自己,
  动作:#selector(sliderEndedTouch),
  关于:[.touchUpInside,.touchUpOutside]
)

用它来完结这个方针,在盛行的布景下,在盛行的布景下盛行起来。

这些,总算到了开端紧缩这些图画的时候了。

在MainViewController.swift的顶部增加以下特点:

小包紧缩行列=  OperationQueue (私有)

操作或许是一种办法的深重工作,运用程序的其他部分。保证开端执行还能够撤销任何新的活动。例如,在撤销当前使命之前,这是一项使命。

resetLabels()在调用里边之后增加以下行updateImages()

紧缩机遇.cancelAllOperations()

这会在新使命撤销之前没有会中增加的一切操作。假如这一步,您或许会在检查中设置过错紧缩质量的图画。

将以下内容替换为compressJPGImage(with:)以下内容:

// 1 
jpgImageView.image =无
jpgActivityIndi​​cator.startAnimating()
// 2
紧缩或许.addOperation {
  // 3护卫让数据=  self 
  .originalImage.jpegData (compressionQuality: quality) else {
    回来
  }
  // 4 
  DispatchQueue .main.async {
     self .jpgImageView.image =  UIImage(数据:数据)
    // TODO:在此处增加图画巨细... 
    // TODO:在此处增加紧缩时刻... 
    // TODO :在此处举办同享按钮...
    UIView .animate(withDuration: 0.3 ) {
       self .jpgActivityIndi​​​​cator.stopAnimating()
    }
  }
}

运用的代码,您:

  1. 删除旧图画并发动活动指示器。
  2. 将紧缩使命增加到界说的操作行列中。
  3. 运用质量参数紧缩原始图画并将其转换为Data.
  4. 从紧缩数据创立一个 UIImage 并在主线程上更新图画视图。请记住,UI 操作应一直发生在主线程上。您将很快向此办法增加更多代码。

这便是运用 JPEG 编解码器紧缩图画的过程。要增加 HEIC 图画紧缩,请将以下内容替换为compressHEICImage(with:)

heicImageView.image =  nil
heicActivityIndi​​cator.startAnimating()
紧缩行列.addOperation {
  做{
    让数据= 尝试 自我.originalImage.heicData(compressionQuality:质量)
    DispatchQueue .main.async {
       self .heicImageView.image =  UIImage (data: data)
       // TODO:在此处增加图画巨细... 
      // TODO:在此处增加紧缩时刻... 
      // TODO:在此处禁用同享按钮.. .
      UIView .animate(withDuration: 0.3 ) {
         self .heicActivityIndi​​cator.stopAnimating()
      }
    }
  } catch {
     print ( "创立 HEIC 数据时犯错:\(error.localizedDescription) " )
  }
}

HEIC 图画紧缩办法只要一个区别。UIImage+Additions.swift图画数据在当前为空的辅佐办法中紧缩。

打开UIImage+Additions.swift你会发现一个空的heicData(compressionQuality:).在增加办法的内容之前,您需求一个自界说过错类型。

在扩展的顶部增加以下内容:

枚举 HEICError :过错{
   case heicNotSupported
   case cgImageMissing
   case couldNotFinalize
}

Error枚举包括一些案例,以说明运用 HEIC 紧缩图画时或许呈现的各种问题。并非一切 iOS 设备都能够捕获 HEIC 内容,但大多数运转 iOS 11 或更高版别的设备都能够读取和修改此内容。

将内容替换为heicData(compressionQuality:)

// 1 
let data =  NSMutableData ()
 guard  let imageDestination = 
  CGImageDestinationCreateWithData (
    数据,AVFileType .heic作为 CFString,1,nil
  )
  不然{
    抛出 HEICError .heicNotSupported
}
// 2 
guard  let cgImage =  self .cgImage else {
   throw  HEICError .cgImageMissing
}
// 3 个
让选项:NSDictionary  = [
  kCGImageDestinationLossyCompressionQuality:compressionQuality
]
// 4 
CGImageDestinationAddImage (imageDestination, cgImage, options)
 guard  CGImageDestinationFinalize (imageDestination) else {
   throw  HEICError .couldNotFinalize
}
将数据作为 数据回来

是时候打破这个了:

  • 首先,您需求一个空的数据缓冲区。此外,您还能够运用CGImageDestinationCreateWithData(_:_:_:_:).此办法是图画 I/O结构的一部分,充任一种容器,能够在写入图画数据之前增加图画数据并更新其特点。假如此处呈现问题,则说明 HEIC 在设备上不可用。
  • 您需求保证有图画数据可供运用。
  • 传递给办法的参数运用 key 运用kCGImageDestinationLossyCompressionQuality。您正在运用该NSDictionary类型,由于CoreGraphics需求它。
  • 最终,将图画数据与选项一起运用到目的地。CGImageDestinationFinalize(_:)完结 HEIC 图画紧缩,true假如成功则回来。

构建并运转。您现在应该看到图画将根据滑块的值*发生变化。*底部图画应该需求更长的时刻才干呈现,由于 HEIC 图画紧缩涉及更多,由于它能够节约更多磁盘空间。

适用于 iOS 的 HEIC 图像压缩

丈量时刻

现在,您或许会以为整个 HEIC 事情并不令人印象深刻。现在唯一清楚的是,运用 HEIC 紧缩图画很慢。好吧,接下来你会看到 HEIC 文件要小多少。

项目中包括一个名为Data+Additions.swift的帮助文件,其间包括一个核算特点,能够漂亮地打印对象的巨细Data。此特点运用Foundation结构的便捷ByteCountFormatter来格局化字节巨细。

MainViewController.swift中,将TODO: Add image size here…insidecompressJPGImage(with:)替换为:

自我.jpgSizeLabel.text = data.prettySize

与 JPEG 办法相同,将TODO: Add image size here…insidecompressHEICImage(with:)替换为:

自我.heicSizeLabel.text = data.prettySize

这将更新尺度标签以反映每个图画的尺度。

构建并运转。您应该当即看到运用 HEIC 能够节约多少空间,这更有用。

适用于 iOS 的 HEIC 图像压缩

在 HEIC 和 JPEG 之间进行挑选时要考虑的最终一个因素是时刻。紧缩所需的时刻是需求考虑的关键数据。假如您的运用程序需求空间速度,那么 HEIC 或许不是您的最佳挑选。

MainViewController.swift的顶部增加以下内容:

私有 让numberFormatter =  NumberFormatter ()

格局化程序有助于使数字更具可读性。此格局化程序将使读取准确的时刻间隔变得更简单。

在 的底部viewDidLoad(),就在 之前updateImages(),增加以下代码:

numberFormatter.maximumSignificantDigits =  1
numberFormatter.maximumFractionDigits =  3

这会将格局化程序装备为限制其输出,由于两种紧缩办法之间的差异是显而易见的。假如两者更挨近,那么更高水平的精度将是有益的。

在之后增加以下办法resetLabels()

私家 func  elapsedTime ( startDate : Date ) -> String ? {
   let endDate =  Date ()
   let interval = endDate.timeIntervalSince(startDate)
   let intervalNumber =  NSNumber (值:interval)
  回来numberFormatter.string(来自:intervalNumber)
}

此办法运用您之前声明的格局化程序。它承受开端日期,然后根据该日期核算持续时刻,并运用数字格局化程序回来一个可选字符串。

在里边compressJPGImage(with:)增加这个到办法的顶部:

startDate = 日期()

接下来,替换TODO: Add compression time here…insidecompressJPGImage(with:)

if  let time =  self .elapsedTime(from: startDate) {
   self .jpgTimeLabel.text =  " \(time) s"
}

当即记载开端日期,保证办法的一切部分都有助于核算的持续时刻。一旦在主行列上完结解码,就会设置时刻标签。

像曾经相同,您需求为 HEIC 图画紧缩办法增加随附的逻辑。将此增加到顶部compressHEICImage(with:)

startDate = 日期()

并将**TODO: Add compression time here…**替换为以下内容:

if  let time =  self .elapsedTime(from: startDate) {
   self .heicTimeLabel.text =  " \(time) s"
}

在输入或复制类似的代码时,请保证您设置了正确的标签。请注意,这heicTimeLabel是在 HEIC 办法和jpgTimeLabelJPG 办法中设置的。

构建并运转。

适用于 iOS 的 HEIC 图像压缩

现在您能够做出充分知情的决定。JPG 紧缩速度十分快,但价值是图画更大。相反,HEIC 图画更小,但紧缩更慢。

了解用户的设备是一件好事。由于 HEIC 需求更长的时刻,因而您或许会在电池电量缺乏时推延节约空间。您还能够检查设备的可用存储空间。假如磁盘已满 75%,请一直挑选 HEIC 图画紧缩。

同享 HEIC

最终要考虑的一件事是同享 HEIC 图画。JPEG 紧缩算法多年来一直是网络上的标准,但 HEIC 必须供给的灵活性和节约空间令人印象深刻。

许多精心设计的网站现已运用 JPEG 紧缩其内容。假如一个站点的文件现已很小,那么节约 50% 就没有那么诱人了。但节约一半的高质量 iPhone 相片空间更有意义。

虽然现在或许不是在网络上全面运用 HEIC 的适宜机遇,但有些网站供给了上传 HEIC 相片的支撑。在 Apple 生态系统中,其他运用程序处理 HEIC 内容应该没有问题。同享内容时,供给同享格局的挑选是有益的。

在下面增加以下办法updateImages()

私家 函数 shareImage(_ 图画:UIImage){
  让avc =  UIActivityViewController(
    活动项目:[图片],
    运用活动:无
  )
  现在(avc,动画:真)
}

此办法同享以任一格局紧缩的图画。UIImage类负责处理其底层格局,因而您不必这样做。

要运用它,请shareButtonPressed()MainViewController.swift中增加以下内容:

让avc =  UIAlertController (
  标题:“同享”,
  消息:“你想如何同享?” ,
  首选款式:.alert
)
假如 让jpgImage = jpgImageView.image {
  avc.addAction( UIAlertAction (title: "JPG" , style: .default) { _  in 
    self .shareImage(jpgImage)
  })
}
假如 让heicImage = heicImageView.image {
  avc.addAction( UIAlertAction (title: "HEIC" , style: .default) { _  in 
    self .shareImage(heicImage)
  })
}
avc.addAction( UIAlertAction (title: "Cancel" , style: .cancel, handler: nil ))
现在(avc,动画:真)

这为此运用程序设置了简单的同享功用,由于图画视图中现已有两个紧缩图画。关于将一切图画存储为 HEIC 的实在运用程序,您需求在同享之前将图画转换为 JPEG。

增加到示例运用程序的最终一项生活质量功用是在没有可用图画时阻止同享。关于较大的文件,HEIC 图画紧缩或许会失败或需求更长时刻。在此期间,禁用同享按钮以避免混杂并保护良好的用户体会是有益的。

里边updateImages()增加:

导航项.leftBarButtonItem ?.isEnabled = 假

此行在紧缩开端之前禁用同享按钮。

接下来,将每次呈现的**TODO: Disable share button here…**替换为:

自.navigationItem.leftBarButtonItem ?.isEnabled = 真

每次紧缩完结后,同享按钮会从头启用。假如 HEIC 图画紧缩仍在处理中,您只会在警报中看到 JPG 选项。关于您的运用程序,比及这两个选项都可用或许更有意义。

构建并运转。

适用于 iOS 的 HEIC 图像压缩

恭喜,示例运用程序已完结!

结论

您现在应该对 HEIC 及其优点和缺点有所了解。HEIC 有很多用例,随着时刻的推移,它只会越来越受欢迎。

回忆 HEIC 的好处:

  • 与 JPEG 相比,文件巨细小 50%。
  • 包括许多图画项。
  • 图画派生,非破坏性修改。
  • 图画序列,例如实时相片。
  • 用于存储深度或 HDR 数据的辅佐图画项。
  • 图画元数据,例如方位或相机信息。

下载项目材料与原文地址

这里也推荐一些面试相关的内容!

  • ① BAT等各个大厂iOS面试真题+答案大全

  • ② iOS中高级开发必看的抢手书本(经典必看)

  • ③ iOS开发高级面试”简历制造”指导

  • ④ iOS面试流程到基础知识大全