【问题标题】:Is there a better way for tiling Images in iphone有没有更好的方法在 iphone 中平铺图像
【发布时间】:2011-06-28 22:16:25
【问题描述】:

目前,尝试通过 URL 下载图像,并以 Apple 商店的 PhotoScroller 应用程序的方式平铺这些图像。 最大图像尺寸为 4000 * 4000,为 RGB 格式。我用 256 * 256 的瓷砖尺寸平铺这些图像。 平铺图像并将文件写入磁盘需要很长时间。 如果可以平铺文件并在 iphone 上加载,则正在寻找更好的方法。总共 4 个 URL 调用,每个 URL 调用获取图像并通过平铺过程并调用 PhotoScroller 应用程序以在 iphone 上启动这些图像。

如果有人遇到过此类问题并了解更多,您能否分享一些想法。

-(void) startImageDownloading
{

if (!isImageRequested)
{
    isImageRequested = YES;
    self.responseData = [NSMutableData data];

    URL1 = @"http://www.abc.com/image_id=1&size=1"; 
    NSURLRequest *request1 = [NSURLRequest requestWithURL:[NSURL URLWithString:URL1]];
    self.connection1= [[[NSURLConnection alloc] initWithRequest:request1 delegate:self] autorelease];

    URL2 = @"http://www.abc.com/image_id=2&size=2"; 
    NSURLRequest *request2 = [NSURLRequest requestWithURL:[NSURL URLWithString:URL2]];
    self.connection2= [[[NSURLConnection alloc] initWithRequest:request2 delegate:self] autorelease];

    URL3 = @"http://www.abc.com/image_id=3&size=3"; 
    NSURLRequest *request3 = [NSURLRequest requestWithURL:[NSURL URLWithString:URL3]];
    self.connection3= [[[NSURLConnection alloc] initWithRequest:request3 delegate:self] autorelease];


    URL4 = @"http://www.abc.com/image_id=4&size=4";     
    NSURLRequest *request4 = [NSURLRequest requestWithURL:[NSURL URLWithString:URL4]];
    self.connection4= [[[NSURLConnection alloc] initWithRequest:request4 delegate:self] autorelease];

}

}



- (void)saveTilesOfSize:(CGSize)size 
           forImage:(UIImage*)image 
        toDirectory:(NSString*)directoryPath 
        usingPrefix:(NSString*)prefix
   {

CGFloat cols = [image size].width / size.width;
CGFloat rows = [image size].height / size.height;

int fullColumns = floorf(cols);
int fullRows = floorf(rows);

CGFloat remainderWidth = [image size].width - (fullColumns * size.width);
CGFloat remainderHeight = [image size].height - (fullRows * size.height);


if (cols > fullColumns) fullColumns++;
if (rows > fullRows) fullRows++;

CGImageRef fullImage = [image CGImage];

for (int y = 0; y < fullRows; ++y) {
    for (int x = 0; x < fullColumns; ++x) {

        CGSize tileSize = size;

        if (x + 1 == fullColumns && remainderWidth > 0) {
            // Last column
            tileSize.width = remainderWidth;
        }
        if (y + 1 == fullRows && remainderHeight > 0) {
            // Last row
            tileSize.height = remainderHeight;
        }

        CGImageRef tileImage = CGImageCreateWithImageInRect(fullImage,(CGRect){{x*size.width, y*size.height},tileSize});

        NSData *imageData = UIImagePNGRepresentation([UIImage imageWithCGImage:tileImage]);
        CGImageRelease(tileImage);
        NSString *path = [NSString stringWithFormat:@"%@/%@%d_%d.png",directoryPath, prefix, x, y];

        [imageData writeToFile:path atomically:NO];

    }
}    
}

【问题讨论】:

    标签: iphone objective-c catiledlayer


    【解决方案1】:

    似乎您正在重建整个图像,然后为每个图块将其保存到磁盘(并且可能再次渲染它),这是一个资源消耗。

    试试这个方法:

    1. 将切片保存到磁盘,并并行

    2. 从磁盘读取切片并通过在上下文中绘制它在内存中构建它们。看看 UIGraphicsBeginImageContext 和 [UIImage drawInRect]。 (不确定资源使用是否优于 CGImageCreateWithImageInRect)

    3. 完成后,将其保存到磁盘。参见 UIGraphicsGetImageFromCurrentImageContext

    如果您在图像变大时遇到内存问题,您可能需要调整 #3,即为图块数量添加一个阈值,以便在达到内存限制之前知道何时将其保存到磁盘。

    此外,我没有在您的代码中看到您如何渲染要显示的图像,但 setNeedsDisplayInRect 对于仅在指定的矩形上渲染很有用。但是,如果您使用的是 CATiledLayer,那么这种组合会出现一些问题,请尝试更多地使用它或研究解决方案,直到您完全得到您想要的为止。

    【讨论】:

    • 谢谢曼尼。我想如果我可以将文件保存到磁盘,并行将帮助我解决问题。但不确定你是如何并行执行的?你的意思是使用 NSOperationQueue 吗?
    • 我想像这样:4个异步连接并行检索并保存到磁盘,然后在主线程上执行渲染。抱歉并行混淆,我的意思是多个线程将同时从服务器检索和处理数据。
    【解决方案2】:

    由于您的图像是 4000 x 4000 且采用 RGB 格式,因此下载和平铺在 iPhone 上肯定会花费很长时间,因为这是一个 CPU 密集型计算。

    我已经看到通过从 UIImagePNGRepresentation 切换到 UIImageJPEGRepresentation 来保存文件的显着改进,因此您可以尝试一下。

    对于平铺,解决它的最佳方法是在服务器上而不是在 iphone 上进行。

    【讨论】:

    • 我确实尝试了 UIImageJEPGRepresentation 并没有解决我的问题。我可以考虑将图像平铺在服务器上而不是在 iPhone 上。
    • 将图像平铺在服务器上将是您最好的方法,Jeff Lamarche 有一篇关于图像平铺的博文here
    • 谢谢沃纳。但是如果我必须得到那些像真实数据一样的平铺图像,这意味着图像经常变化并且必须更新,我该如何实现它。由于我从 URL 获得的图像就像真实的实时数据。因此,每次从服务器获取更新数据时,我都会进行平铺。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多