Есть ли лучший способ для плитки изображения в iphone - PullRequest
0 голосов
/ 29 июня 2011

В настоящее время мы пытаемся загрузить изображения по URL-адресам и расположить их в порядке, аналогичном тому, как приложение PhotoScroller было сделано в магазине Apple. Наибольший размер изображения 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];

    }
}    
}

Ответы [ 2 ]

1 голос
/ 29 июня 2011

Похоже, что вы восстанавливаете целое изображение, а затем сохраняете его на диск для каждой плитки (и, вероятно, визуализируете его снова), это источник ресурсов.

Попробуйте этот подход:

  1. сохранить плитки на диск, и параллельно ,

  2. читатьплитки с диска и построить их в памяти, нарисовав его в контексте.Взгляните на UIGraphicsBeginImageContext и [UIImage drawInRect].(Не уверен, что использование ресурсов лучше, чем CGImageCreateWithImageInRect)

  3. По завершении сохраните его на диск.См. UIGraphicsGetImageFromCurrentImageContext

Если вы сталкиваетесь с проблемой памяти, когда изображение становится больше, вы можете настроить # 3, то есть добавить порог к числу плиток, чтобы знать, когда сохранять его на дискдо достижения предела памяти.

Кроме того, я не видел в вашем коде, как вы рендеринг изображения для отображения, но setNeedsDisplayInRect полезно для этого для отображения только на указанном прямоугольнике.Однако, если вы используете CATiledLayer, с этой комбинацией будут некоторые проблемы, попробуйте поиграть с ней или поищите решение, пока не получите его в точности так, как вы этого хотите.

1 голос
/ 29 июня 2011

Поскольку ваши изображения имеют размер 4000 x 4000, а в RGB загрузка и разбиение на листы на iPhone наверняка займут много времени, поскольку это требует интенсивной загрузки ЦП.

Я видел существенные улучшения для сохраненияфайл, переключившись с UIImagePNGRepresentation на UIImageJPEGRepresentation, так что вы можете попробовать это.

Для наилучшего способа решения проблемы - это сделать это на сервере, а не на iphone.

...