Swift 4 Binary Approach zum Komprimieren von Bildern
Ich glaube, es ist ziemlich spät, diese Frage zu beantworten, aber hier ist meine Lösung für die Frage, die optimiert ist. Ich verwende die binäre Suche , um den optimalen Wert zu finden. Wenn beispielsweise ein normaler Subtraktionsansatz zum Erreichen von 62% 38 Komprimierungsversuche erfordern würde, würde der Ansatz der * binären Suche ** die erforderliche Lösung in max log (100) = etwa 7 Versuchen erreichen.
Ich möchte Sie jedoch auch darüber informieren, dass sich die UIImageJPEGRepresentationFunktion nicht linear verhält, insbesondere wenn die Zahl nahe 1 liegt. Hier ist der Screenshot, in dem wir sehen können, dass das Bild nicht mehr komprimiert wird, nachdem der Gleitkommawert> 0,995 ist. Das Verhalten ist ziemlich unvorhersehbar, daher ist es besser, einen Delta-Puffer zu haben, der solche Fälle behandelt.

Hier ist der Code dafür
extension UIImage {
func resizeToApprox(sizeInMB: Double, deltaInMB: Double = 0.2) -> Data {
let allowedSizeInBytes = Int(sizeInMB * 1024 * 1024)
let deltaInBytes = Int(deltaInMB * 1024 * 1024)
let fullResImage = UIImageJPEGRepresentation(self, 1.0)
if (fullResImage?.count)! < Int(deltaInBytes + allowedSizeInBytes) {
return fullResImage!
}
var i = 0
var left:CGFloat = 0.0, right: CGFloat = 1.0
var mid = (left + right) / 2.0
var newResImage = UIImageJPEGRepresentation(self, mid)
while (true) {
i += 1
if (i > 13) {
print("Compression ran too many times ") // ideally max should be 7 times as log(base 2) 100 = 6.6
break
}
print("mid = \(mid)")
if ((newResImage?.count)! < (allowedSizeInBytes - deltaInBytes)) {
left = mid
} else if ((newResImage?.count)! > (allowedSizeInBytes + deltaInBytes)) {
right = mid
} else {
print("loop ran \(i) times")
return newResImage!
}
mid = (left + right) / 2.0
newResImage = UIImageJPEGRepresentation(self, mid)
}
return UIImageJPEGRepresentation(self, 0.5)!
}
}