ios - 像在 WhatsApp 上一样在 iPhone 上压缩图像
问题描述
我正在尝试在 Swift 编程语言中找到一种图像压缩算法,就像在 WhatsApp Messenger 中一样。在Android OS 下的Java 编程语言我发现很快,而在iOS 平台下有困难。
这是Android的图像压缩算法:
public static File saveBitmapToFile(File file){
try {
// BitmapFactory options to downsize the image
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
o.inSampleSize = 6;
// factor of downsizing the image
FileInputStream inputStream = new FileInputStream(file);
//Bitmap selectedBitmap = null;
BitmapFactory.decodeStream(inputStream, null, o);
inputStream.close();
// The new size we want to scale to
final int REQUIRED_SIZE=75;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while(o.outWidth / scale / 2 >= REQUIRED_SIZE &&
o.outHeight / scale / 2 >= REQUIRED_SIZE) {
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
inputStream = new FileInputStream(file);
Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, o2);
inputStream.close();
// here i override the original image file
file.createNewFile();
FileOutputStream outputStream = new FileOutputStream(file);
selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 70 , outputStream);
return file;
} catch (Exception e) {
return null;
}
}
该算法将图像压缩到 100 KB。如果您能告诉我如何将此代码复制到 Swift 编程语言中,我将不胜感激。
解决方案
这个函数应该这样做:
func compressImage(_ image: UIImage?) -> UIImage? {
var actualHeight = Float(image?.size.height ?? 0.0)
var actualWidth = Float(image?.size.width ?? 0.0)
let maxHeight: Float = 600.0
let maxWidth: Float = 800.0
var imgRatio: Float = actualWidth / actualHeight
let maxRatio: Float = maxWidth / maxHeight
let compressionQuality: Float = 0.5 //50 percent compression
if actualHeight > maxHeight || actualWidth > maxWidth {
if imgRatio < maxRatio {
//adjust width according to maxHeight
imgRatio = maxHeight / actualHeight
actualWidth = imgRatio * actualWidth
actualHeight = maxHeight
} else if imgRatio > maxRatio {
//adjust height according to maxWidth
imgRatio = maxWidth / actualWidth
actualHeight = imgRatio * actualHeight
actualWidth = maxWidth
} else {
actualHeight = maxHeight
actualWidth = maxWidth
}
}
let rect = CGRect(x: 0.0, y: 0.0, width: CGFloat(actualWidth), height: CGFloat(actualHeight))
UIGraphicsBeginImageContext(rect.size)
image?.draw(in: rect)
let img: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
let imageData = img?.jpegData(compressionQuality: CGFloat(compressionQuality))
UIGraphicsEndImageContext()
if let imageData = imageData {
return UIImage(data: imageData)
}
return nil
}
用法:
secondHighest.image = compressImage(image, quality: 0.0)
//你总是可以添加这样的参数来控制质量
Highest.image = compressImage(image, quality: 0.6)//bottom
结果:
推荐阅读
- javascript - TS2769:没有重载匹配此调用
- sql - 在 postgreSQL 查询中没有数据的月份返回 0
- c++ - gps.location.isUpdated() 条件不起作用
- json - 如何在 Blazor 中使用 Http.GetFromJsonAsync 将模型对象传递给控制器函数
- ios - 使用两个标准对列表进行排序-objective-c
- python - 使用 Pyplot 绘制隐藏单元激活
- javascript - 样式化组件客户端和服务器端的不同道具
- docker - SSL 证书生成子域使用反向代理和letsencrypt失败
- c++ - clang-format:在预处理器指令的关闭中对齐注释样式
- google-cloud-platform - 不同组织拥有的项目之间的 HA VPN 实施