gpt4 book ai didi

ios - UIImageJPEGRepresentation 收到内存警告

转载 作者:可可西里 更新时间:2023-11-01 05:05:32 26 4
gpt4 key购买 nike

我在使用 UIImageJPEGRepresentation 时收到内存警告,有什么办法可以避免这种情况?它不会使应用程序崩溃,但我想尽可能避免它。它确实间歇性地不运行 [[UIApplication sharedApplication] openURL:url];

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
NSData *imageToUpload = UIImageJPEGRepresentation(image, 1.0);

// code that sends the image to a web service (omitted)
// on success from the service
// this sometime does not get run, I assume it has to do with the memory warning?
[[UIApplication sharedApplication] openURL:url];
}

最佳答案

使用 UIImageJPEGRepresentation(您通过 UIImage 往返 Assets )可能会出现问题,因为使用 1.0 的 compressionQuality ,生成的 NSData 实际上可能比原始文件大得多。 (另外,您在 UIImage 中持有图像的第二个副本。)

例如,我只是从 iPhone 的照片库中随机选择了一张图片,原始 Assets 为 1.5mb,但是 UIImageJPEGRepresentation 生成的 NSData 带有 1.0 的压缩质量 需要 6.2mb。将图像保存在 UIImage 中,本身可能会占用更多内存(因为如果未压缩,它可能需要,例如,每个像素四个字节)。

相反,您可以使用 getBytes 方法获取原始 Assets :

static NSInteger kBufferSize = 1024 * 10;

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSURL *url = info[UIImagePickerControllerReferenceURL];

[self.library assetForURL:url resultBlock:^(ALAsset *asset) {
ALAssetRepresentation *representation = [asset defaultRepresentation];
long long remaining = representation.size;
NSString *filename = representation.filename;

long long representationOffset = 0ll;
NSError *error;
NSMutableData *data = [NSMutableData data];

uint8_t buffer[kBufferSize];

while (remaining > 0ll) {
NSInteger bytesRetrieved = [representation getBytes:buffer fromOffset:representationOffset length:sizeof(buffer) error:&error];
if (bytesRetrieved <= 0) {
NSLog(@"failed getBytes: %@", error);
return;
} else {
remaining -= bytesRetrieved;
representationOffset += bytesRetrieved;
[data appendBytes:buffer length:bytesRetrieved];
}
}

// you can now use the `NSData`

} failureBlock:^(NSError *error) {
NSLog(@"assetForURL error = %@", error);
}];
}

这避免了在 UIImage 中暂存图像,并且生成的 NSData 可以(无论如何对于照片)相当小。请注意,这还有一个优点,即它也保留了与图像关联的元数据。

顺便说一句,虽然上面的内容代表了显着的内存改进,但您可能会看到内存减少的机会更显着:具体来说,不是一次将整个 Assets 加载到 NSData 中,而是现在可以流式传输 Assets (子类 NSInputStream 使用此 getBytes 例程在需要时获取字节,而不是一次将整个内容加载到内存中)。此过程涉及一些麻烦(请参阅 BJ Homer's article on the topic ),但如果您正在寻找显着减少内存占用的方法,那就是这样。这里有几种方法(BJ,使用一些暂存文件并从中流式传输等),但关键是流式传输可以显着减少内存占用。

但是通过避免 UIImageJPEGRepresentation 中的 UIImage(这避免了图像占用的内存以及 的更大的 NSData UIImageJPEGRepresentation yields),你可能会取得相当大的进展。此外,您可能希望确保一次内存中没有此图像数据的冗余副本(例如,不要将图像数据加载到 NSData 中,然后构建第二个NSData 用于 HTTPBody ...看看你是否可以一举完成)。如果情况变得更糟,您可以采用流媒体方法。

关于ios - UIImageJPEGRepresentation 收到内存警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25248294/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com