2011-06-28 7 views
0

現在、アップルストアでPhotoScrollerアプリがどのように行われているかをURLで画像をダウンロードし、それらの画像をタイリングしようとしています。 最大画像サイズは4000 * 4000で、RGB形式です。これらのイメージをタイルサイズ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

あなたのイメージは、x 4000 4000であり、それがCPU集中的計算であるため、RGBにダウンロードし、タイリングは確かにiPhone上で長い時間がかかるとしているので。

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

ワーナーに感謝します。しかし、実際のデータのようなタイル張りの画像を取得しなければならない場合は、画像が頻繁に変更され、更新する必要があります。 URLから取得する画像は実際のライブデータのようなものなので、そしてその理由のために私はサーバから更新されたデータを得るたびに並べていました。 – lifemoveson

関連する問題