【问题标题】:iPhone app take a lot of memory while appending images and loading in uiwebviewiPhone 应用程序在 uiwebview 中附加图像和加载时占用大量内存
【发布时间】:2014-11-24 07:21:43
【问题描述】:

我想显示一个 tiff 文件,比如说 25 页。我必须通过滚动逐页显示 tiff 文件。仅供参考,我不想使用来自 github 的 NSTiffSplitter,我想在用户向下滚动 uiwebview 的滚动视图时下载下一页。 我正在下载第一页字节(数组),将其转换为 .jpeg 文件(image1.jpeg)并将其写入文档目录并将下载的页面加载到 UIWebview 中。现在,当用户在滚动视图结束时向下滑动时,我将 tiff 文件的第二页下载为字节,将其转换为 .jpeg(image2.jpeg),将其保存到文档目录并附加第一页(image1.jpeg),然后将附加的图像加载到 UIWebview。

这适用于假设 7 页,在 8 到 10 应用程序显示内存警告和崩溃。让我也发布代码。

我的想法是 imageByCombiningImage 正在消耗内存而不是释放它。需要专家建议。

-(void)saveAndDisplayFullImageiPad:(NSDictionary *)dicIn{
    int pageNumber = [[dicIn objectForKey:@"SortNo"]intValue];//page number comes in web service response
    self.currentFilePageCount = [[dicIn objectForKey:@"PagesCount"]intValue];
    NSArray *arrayOfBytes = [dicIn objectForKey:@"FileBytes"];
    if (arrayOfBytes != nil && [arrayOfBytes count] > 0) {

    unsigned c = arrayOfBytes.count;
    uint8_t *bytes = malloc(sizeof(*bytes) * c);
    unsigned i;
    for (i = 0; i < c; i++){
        NSString *str = [arrayOfBytes objectAtIndex:i];
        int byte = [str intValue];
        bytes[i] = (uint8_t)byte;
    }
    NSData  *data = [NSData dataWithBytes:(const void *)bytes length:sizeof(unsigned char)*c];
    free(bytes);

    NSString *fileNameCPath=[dicIn objectForKey:@"FilePath"];
    NSString *fileNamePlusExtension = [[fileNameCPath componentsSeparatedByString:@"\\"] lastObject];
    NSString *justFileName = [[fileNamePlusExtension componentsSeparatedByString:@"." ]firstObject];

    self.standardTiffPageName = [justFileName stringByAppendingString:@"PageNumber"];

    NSString *fileWithPageNum = [justFileName stringByAppendingString:[NSString stringWithFormat:@"PageNumber%d.jpeg",pageNumber]];
    NSString *fileWithDirPath = [[[AppSettings sharedAppSettings]getDocumentDirectory] stringByAppendingPathComponent:fileWithPageNum];//document directory path appended
    NSLog(@"filePathWritten = %@",fileWithDirPath);
    [data writeToFile:fileWithDirPath atomically:YES];

    self.tiffMainPageName = fileWithDirPath;

    [self.tiffPagesNameArray addObject:fileWithDirPath];//just saving pages path names

    if (pageNumber == 1) {
        self.tiffMainPageName = fileWithDirPath;//tiffMainPageName has the appended images
    }
    if (pageNumber > 1) {

        UIImage *img1 = [UIImage imageWithContentsOfFile:self.tiffMainPageName];
        UIImage *img2 = [UIImage imageWithContentsOfFile:fileWithDirPath];
        UIImage *finalImage = [self imageByCombiningImage:img1 withImage:img2];
        NSData *dataFinalImage = UIImageJPEGRepresentation(finalImage, 0.5);
        [dataFinalImage writeToFile:self.tiffMainPageName atomically:YES];
    }

}
[self.webView1 loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:self.tiffMainPageName]]];
self.tiffPageDownloadComplete = YES;
}

- (UIImage*)imageByCombiningImage:(UIImage*)image1 withImage:(UIImage*)image2 {

CGSize size = CGSizeMake(image1.size.width, image1.size.height + image2.size.height);

UIGraphicsBeginImageContext(size);

[image1 drawInRect:CGRectMake(0,0,size.width, image1.size.height)];
[image2 drawInRect:CGRectMake(0,image1.size.height,size.width, image2.size.height)];

UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return finalImage;
}

【问题讨论】:

    标签: iphone image memory uiwebview crash


    【解决方案1】:

    我认为您只是在创建一个最终太大而无法放入内存的图像。而不是通过附加上一页的图像来创建一个越来越大的图像,您可以只在前一页的下方显示下一页的图像。

    对于 webview,您始终可以生成一个包含所需图像的新“html 页面”。使用这样的功能:

    - (NSString*)htmlStringWithImagesOnPaths:(NSArray*)imagePaths {
        NSString* html = @"<html><head><title></title></head><body>";
    
        for(NSString* imagePath in imagePaths)
            html = [html stringByAppendingString:[NSString stringWithFormat:@"<img src=\"%@\">", imagePath]];
    
        return [html stringByAppendingString:@"</body></html>"];
    }
    

    然后你会这样做而不是[self.webView1 loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:self.tiffMainPageName]]]

    NSString *documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0];
    [webView loadHTMLString:[self htmlStringWithImagesOnPaths:self.imagePaths] baseURL:[NSURL fileURLWithPath: documentsDirectoryPath]];
    

    在这种情况下,您应该在htmlStringWithImagesOnPaths: 方法的imagePaths 参数中提供一组相对路径(相对于文档目录)。

    还有一点 - 我不知道为什么在 NSArray *arrayOfBytes = [dicIn objectForKey:@"FileBytes"]; 之后你要将此字节数组转换为 NSString 然后再转换回字节,然后将其保存到文件中。为什么不立即将其保存到文件中(使用[arrayOfBytes writeToFile:fileWithDirPath atomically:YES])

    祝你好运

    【讨论】:

    • 网页视图显示问号,而不是图像。不适合我。我正在尝试显示文档目录中的图像,而不是捆绑包中的图像。为什么基本 url 是用空字符串创建的。[webView loadHTMLString:[self htmlStringWithImagesOnPaths:self.imagePaths] baseURL:[NSURL URLWithString:@""]];感谢您的帮助
    • @user1994956 好吧,它甚至应该适用于存储在文档目录中的图像。所以可能图像网址不正确。如果您使用的是绝对 URL,则 baseURL 应该没有效果,所以我只是在那里放了一个空字符串(尽管可以是 nil)...... baseURL - 我将编辑我的帖子。
    • @user1994956 有什么消息吗?即使使用所描述的技术,您的应用程序仍然崩溃吗?如果它回答了您的问题,请将帖子标记为答案。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2014-05-11
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多