2011-06-28 35 views
0

目前,試圖通過URL下載圖像,並以Apple Store商店完成PhotoScroller應用程序的方式平鋪這些圖像。 最大的圖像尺寸是4000 * 4000,並且是RGB格式。我用tilesize 256 * 256平鋪這些圖像。 需要很長時間才能平鋪圖像並將文件寫入磁盤。 正在尋找更好的方法,如果它可能平鋪文件和加載在iphone上。共有4個URL調用和每個URL調用獲取圖像,並通過平鋪過程並調用PhotoScroller應用程序在iphone上啓動這些圖像。有沒有更好的方式平鋪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]; 

    } 
}  
} 

回答

1

好像你正在重建整個圖像,然後將其保存到每個磁貼的磁盤(大概是再次渲染),這是一個資源豬。

試試這個辦法:

  1. 節省瓷磚到磁盤, 和並行

  2. 從磁盤讀取的瓷磚,並通過在上下文繪製它構建在內存中。看看UIGraphicsBeginImageContext和[UIImage drawInRect]。 (不確定資源使用是否優於CGImageCreateWithImageInRect)

  3. 完成後,將其保存到磁盤。見UIGraphicsGetImageFromCurrentImageContext

如果遇到內存問題,圖像變得更大,你可能需要調整#3,即增加一個閾值的瓦片數目知道什麼時候達到內存限制之前將其保存到磁盤。

此外,我沒有在您的代碼中看到如何渲染圖像,但setNeedsDisplayInRect對於此渲染僅適用於指定的矩形非常有用。但是,如果您使用的是CATiledLayer,那麼這個組合會出現一些問題,請嘗試更多地使用它,或者研究解決方案,直到完全按照您的需要得到它。

+0

+1 ...不錯的回答方式 –

+0

謝謝曼尼。我想如果我可以將文件保存到磁盤,並行將幫助我解決問題。但不知道你是如何平行進行的?你的意思是使用NSOperationQueue嗎? – lifemoveson

+0

我想像這樣:4個異步連接並行檢索並保存到磁盤,然後在主線程上執行渲染。對不起併發的混淆,我的意思是超過1個線程將同時從服務器檢索和處理數據。 – Manny

1

由於您的圖像是4000 X 4000和RGB下載和瓷磚是要採取在iPhone上很長一段時間是肯定的,因爲它是一個CPU密集型計算。

我已經看到通過從UIImagePNGRepresentation切換到UIImageJPEGRepresentation保存文件的重大改進,所以你可以嘗試。

對於平鋪最好的解決方法是在服務器上而不是在iphone上。

+0

我確實嘗試過UIImageJEPGRepresentation,它並沒有解決我的問題。我可以考慮在服務器上平鋪圖像而不是在iphone上。 – lifemoveson

+0

平鋪服務器上的圖像將是您最好的方法,Jeff Lamarche在圖像平鋪[這裏]有一篇博文(http://iphonedevelopment.blogspot.com/2010/10/cutting-large-images-into-tiles -for.html) – werner

+0

謝謝werner。但是,如果我必須得到像實際數據那樣的平鋪圖像,這意味着圖像經常變化並且必須更新,那我該如何實現它。由於我從URL獲得的圖像就像真實的實時數據。因此,每當我從服務器獲取更新的數據時,我都會進行平鋪。 – lifemoveson