iOS二维码生成内存占用
iOS QR code generation memory usage
我使用以下代码在我的应用程序中实现了二维码生成器:
+ (UIImage *)qrCodeForString:(NSString *)qrString withScale:(CGFloat)scale {
CIImage *image = [self createQRForString:qrString];
return [self createNonInterpolatedUIImageFromCIImage:image withScale:scale];
}
+ (UIImage *)createNonInterpolatedUIImageFromCIImage:(CIImage *)image withScale:(CGFloat)scale
{
// Render the CIImage into a CGImage
CGImageRef cgImage = [[CIContext contextWithOptions:nil] createCGImage:image fromRect:image.extent];
// Now we'll rescale using CoreGraphics
UIGraphicsBeginImageContext(CGSizeMake(image.extent.size.width * scale, image.extent.size.width * scale));
CGContextRef context = UIGraphicsGetCurrentContext();
// We don't want to interpolate (since we've got a pixel-correct image)
CGContextSetInterpolationQuality(context, kCGInterpolationNone);
CGContextDrawImage(context, CGContextGetClipBoundingBox(context), cgImage);
// Get the image out
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
// Tidy up
UIGraphicsEndImageContext();
CGImageRelease(cgImage);
return scaledImage;
}
+ (CIImage *)createQRForString:(NSString *)qrString
{
// Need to convert the string to a UTF-8 encoded NSData object
NSData *stringData = [qrString dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Size: %zd", stringData.length);
// Create the filter
CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// Set the message content and error-correction level
[qrFilter setValue:stringData forKey:@"inputMessage"];
[qrFilter setValue:@"L" forKey:@"inputCorrectionLevel"];
// Send the image back
return qrFilter.outputImage;
}
问题是,如果我用一个长字符串调用方法+ (UIImage *)qrCodeForString:(NSString *)qrString withScale:(CGFloat)scale
(但仍然远在QR 码可以包含的限制范围内),内存使用量会疯狂!在真实设备上,应用程序(或整个设备)会崩溃,但在模拟器中,我可以使用计算机的所有内存,生成 QR 码时它会在短时间内上升到超过 1 GB(然后恢复正常,没有明显的内存泄漏痕迹)。是我的代码有问题,还是 Apple 实现的 API 内存使用率高得离谱?
将产生 643.7 MB 内存使用的示例字符串:1234567890qesgyujfghjkoiuyhgfrty¬˙∫ç∂∆˚¨¥©√∂†¥˙˜˚˙©ƒ∂®†
运行 此代码导致以下内存使用情况:
生成二维码前:49.2 MB
生成二维码时:643.7 MB
生成二维码后:49.4 MB(部分内存现在也用于在屏幕上显示图像)
是时候 运行 使用分配工具的工具了,看看您是否能找出导致内存使用量激增的原因。
我终于找到问题了。在缩放图像时,我没有传递屏幕宽度与原始图像大小之间的比率,而是传递了屏幕宽度,使图像放大 750x750 倍。这显然造成了对内存的巨大需求。在简单的 QR 码(短字符串)上,这没有明显的效果,因为原始图像太小了,但是当 QR 码变大时,缩放也需要更多的资源。
我使用以下代码在我的应用程序中实现了二维码生成器:
+ (UIImage *)qrCodeForString:(NSString *)qrString withScale:(CGFloat)scale {
CIImage *image = [self createQRForString:qrString];
return [self createNonInterpolatedUIImageFromCIImage:image withScale:scale];
}
+ (UIImage *)createNonInterpolatedUIImageFromCIImage:(CIImage *)image withScale:(CGFloat)scale
{
// Render the CIImage into a CGImage
CGImageRef cgImage = [[CIContext contextWithOptions:nil] createCGImage:image fromRect:image.extent];
// Now we'll rescale using CoreGraphics
UIGraphicsBeginImageContext(CGSizeMake(image.extent.size.width * scale, image.extent.size.width * scale));
CGContextRef context = UIGraphicsGetCurrentContext();
// We don't want to interpolate (since we've got a pixel-correct image)
CGContextSetInterpolationQuality(context, kCGInterpolationNone);
CGContextDrawImage(context, CGContextGetClipBoundingBox(context), cgImage);
// Get the image out
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
// Tidy up
UIGraphicsEndImageContext();
CGImageRelease(cgImage);
return scaledImage;
}
+ (CIImage *)createQRForString:(NSString *)qrString
{
// Need to convert the string to a UTF-8 encoded NSData object
NSData *stringData = [qrString dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Size: %zd", stringData.length);
// Create the filter
CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// Set the message content and error-correction level
[qrFilter setValue:stringData forKey:@"inputMessage"];
[qrFilter setValue:@"L" forKey:@"inputCorrectionLevel"];
// Send the image back
return qrFilter.outputImage;
}
问题是,如果我用一个长字符串调用方法+ (UIImage *)qrCodeForString:(NSString *)qrString withScale:(CGFloat)scale
(但仍然远在QR 码可以包含的限制范围内),内存使用量会疯狂!在真实设备上,应用程序(或整个设备)会崩溃,但在模拟器中,我可以使用计算机的所有内存,生成 QR 码时它会在短时间内上升到超过 1 GB(然后恢复正常,没有明显的内存泄漏痕迹)。是我的代码有问题,还是 Apple 实现的 API 内存使用率高得离谱?
将产生 643.7 MB 内存使用的示例字符串:1234567890qesgyujfghjkoiuyhgfrty¬˙∫ç∂∆˚¨¥©√∂†¥˙˜˚˙©ƒ∂®†
运行 此代码导致以下内存使用情况: 生成二维码前:49.2 MB 生成二维码时:643.7 MB 生成二维码后:49.4 MB(部分内存现在也用于在屏幕上显示图像)
是时候 运行 使用分配工具的工具了,看看您是否能找出导致内存使用量激增的原因。
我终于找到问题了。在缩放图像时,我没有传递屏幕宽度与原始图像大小之间的比率,而是传递了屏幕宽度,使图像放大 750x750 倍。这显然造成了对内存的巨大需求。在简单的 QR 码(短字符串)上,这没有明显的效果,因为原始图像太小了,但是当 QR 码变大时,缩放也需要更多的资源。