我想压缩图像(相机/照片库),然后将其发送到服务器。我知道我可以按高度和宽度进行压缩,但我想将图像按大小压缩到固定大小(200 KB)并保持原始高度和宽度。JPEGRepresentation 中的比例因子不代表大小,只代表压缩质量。如何在不使用任何第三方库的情况下实现这一点(压缩到固定大小)?谢谢你的帮助。
问问题
31339 次
7 回答
63
下面是一些示例代码,它们将尝试为您压缩图像,使其不超过最大压缩或最大文件大小
CGFloat compression = 0.9f;
CGFloat maxCompression = 0.1f;
int maxFileSize = 250*1024;
NSData *imageData = UIImageJPEGRepresentation(yourImage, compression);
while ([imageData length] > maxFileSize && compression > maxCompression)
{
compression -= 0.1;
imageData = UIImageJPEGRepresentation(yourImage, compression);
}
于 2012-02-29T23:29:22.843 回答
3
一种方法是循环重新压缩文件,直到找到所需的大小。您可以先找到高度和宽度,然后猜测压缩系数(较大的图像压缩更多),然后在压缩后检查大小,然后再次拆分差异。
我知道这不是超级有效,但我不相信有一个单一的调用来实现特定大小的图像。
于 2012-02-29T22:46:09.103 回答
1
在这里,JPEGRepresentation 非常消耗内存,如果我们在 Loop 中使用,那么它的内存消耗非常高。所以使用下面的代码 & ImageSize 不会超过 200KB。
UIImage* newImage = [self captureView:yourUIView];
- (UIImage*)captureView:(UIView *)view {
CGRect rect = view.bounds;
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
UIImage* img = [UIImage alloc]init];
img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSLog(@"img=%@",img);
return img;
}
于 2012-12-12T05:33:00.537 回答
1
我接受了@kgutteridge 的回答,并使用递归为Swift 3.0做了一个类似的解决方案:
extension UIImage {
static func compress(image: UIImage, maxFileSize: Int, compression: CGFloat = 1.0, maxCompression: CGFloat = 0.4) -> Data? {
if let data = UIImageJPEGRepresentation(image, compression) {
let bcf = ByteCountFormatter()
bcf.allowedUnits = [.useMB] // optional: restricts the units to MB only
bcf.countStyle = .file
let string = bcf.string(fromByteCount: Int64(data.count))
print("Data size is: \(string)")
if data.count > (maxFileSize * 1024 * 1024) && (compression > maxCompression) {
let newCompression = compression - 0.1
let compressedData = self.compress(image: image, maxFileSize: maxFileSize, compression: newCompression, maxCompression: maxCompression)
return compressedData
}
return data
}
return nil
}
}
于 2017-04-12T10:41:40.750 回答
1
斯威夫特 4:
extension UIImage {
func compressTo(bytes: Int) -> UIImage {
var compression: CGFloat = 0.9
let maxCompression: CGFloat = 0.1
let maxSize: Int = bytes * 1024
var imageData = jpegData(compressionQuality: compression)!
while imageData.count > maxSize && compression > maxCompression {
compression -= 0.1
imageData = jpegData(compressionQuality: compression)!
}
return UIImage(data: imageData)!
}
}
于 2019-04-26T08:05:47.963 回答
0
在做了一些测试后,我能够找到 图像大小和压缩值之间的关系。由于这种关系对于压缩小于 1 的所有值都是线性的,因此我创建了一个算法来尝试始终将图像压缩到某个值。
//Use 0.99 because at 1, the relationship between the compression and the file size is not linear
NSData *image = UIImageJPEGRepresentation(currentImage, 0.99);
float maxFileSize = MAX_IMAGE_SIZE * 1024;
//If the image is bigger than the max file size, try to bring it down to the max file size
if ([image length] > maxFileSize) {
image = UIImageJPEGRepresentation(currentImage, maxFileSize/[image length]);
}
于 2015-10-22T18:30:31.390 回答
-1
- (UIImage *)resizeImageToSize:(CGSize)targetSize
{
UIImage *sourceImage = captureImage;
UIImage *newImage = nil;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
if (widthFactor < heightFactor)
scaleFactor = widthFactor;
else
scaleFactor = heightFactor;
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
// make image center aligned
if (widthFactor < heightFactor)
{
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
}
else if (widthFactor > heightFactor)
{
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
UIGraphicsBeginImageContext(targetSize);
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if(newImage == nil)
NSLog(@"could not scale image");
return newImage ;
}
于 2013-11-22T06:16:04.490 回答