2013-12-09 3 views
0

У меня есть приложение, в котором пользователь снимает фотографию с помощью камеры, а затем выбирает использовать фотографию. Следующий метод называется:Показан HUD, пока изображение уменьшено размером

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 

В рамках этого метода я проверить NSData длину изображения и размер фактического изображения, если данные (Kb) размер слишком велик, то проверьте еще раз. Таким образом, я уменьшаю только небольшие количества, чтобы сохранить изображение самого высокого качества/размера, а не конкретный размер w/h.

Вопрос Я пытаюсь отобразить HUD для пользователя, пока происходит «масштабирование изображения». HUD не показывает в данный момент, это то, что я пробовал.

// Check if the image size is too large 
if ((imageData.length/1024) >= 1024) { 
    MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 
    HUD.dimBackground = YES; 
    HUD.labelText = NSLocalizedString(@"HUDHomeLoadingTableData", @"Home View Controller - Loading Table Data"); 
    HUD.removeFromSuperViewOnHide = YES; 

    while ((imageData.length/1024) >= 1024) { 
     NSLog(@"While start - The imagedata size is currently: %f KB",roundf((imageData.length/1024))); 

     // While the imageData is too large scale down the image 

     // Get the current image size 
     CGSize currentSize = CGSizeMake(image.size.width, image.size.height); 

     // Resize the image 
     image = [image resizedImage:CGSizeMake(roundf(((currentSize.width/100)*80)), roundf(((currentSize.height/100)*80))) interpolationQuality:kMESImageQuality]; 

     // Pass the NSData out again 
     imageData = UIImageJPEGRepresentation(image, kMESImageQuality); 

    } 

    [HUD hide:YES]; 
} 

Я добавляю HUD в self.view, но это не отображается? Должен ли я, возможно, подумать и о потоковом использовании, если масштабирование изображения будет завершено в фоновом потоке и обновлениях HUD на главном. Я не уверен, когда нужно определить, должны ли определенные части быть на разных потоках?

ответ

0

Вызвать метод масштабирования в фоновом потоке, как это:

if ((imageData.length/1024) >= 1024) { 
    self.HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 
    HUD.dimBackground = YES; 
    HUD.labelText = NSLocalizedString(@"HUDHomeLoadingTableData", @"Home View Controller - Loading Table Data"); 
    HUD.removeFromSuperViewOnHide = YES; 
    self.scaledImageData = imageData; 
    [self performSelectorInBackground:@selector(scaleDown:) withObject:imageData]; 
} 

-(void)scaleDown:(NSData*)imageData 
{ 
    while ((imageData.length/1024) >= 1024) { 
     NSLog(@"While start - The imagedata size is currently: %f KB",roundf((imageData.length/1024))); 
    // While the imageData is too large scale down the image 

    // Get the current image size 
    CGSize currentSize = CGSizeMake(image.size.width, image.size.height); 

    // Resize the image 
    image = [image resizedImage:CGSizeMake(roundf(((currentSize.width/100)*80)), roundf(((currentSize.height/100)*80))) interpolationQuality:kMESImageQuality]; 

    // Pass the NSData out again 
    self.scaledImageData = UIImageJPEGRepresentation(image, kMESImageQuality); 

    } 

    //hide the hud on main thread 
    [self performSelectorOnMainThread:@selector(hideHUD) withObject:nil waitUntilDone:NO]; 
} 

-(void)hideHUD 
{ 
    [self.HUD hide:YES]; 
} 
+0

Если вы используете 'performSelectorInBackground', я считаю, что вы должны определить' @ autoreleasepool' для этого нового потока. – Rob

1

Вы изменения размера только одно изображение? Или несколько? Если делать один, вы можете:

MBProgressHUD *HUD = [self showHUD]; 

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    // do your image resizing here 

    // when done, hide the HUD on the main queue 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self hideHUD:HUD]; 
    }); 
}); 

Где

- (MBProgressHUD *)showHUD 
{ 
    MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 
    HUD.dimBackground = YES; 
    HUD.labelText = NSLocalizedString(@"HUDHomeLoadingTableData", @"Home View Controller - Loading Table Data"); 
    HUD.removeFromSuperViewOnHide = YES; 

    return HUD; 
} 

- (void)hideHUD:(MBProgressHUD *)HUD 
{ 
    [HUD hide:YES]; 
} 

Если изменение размера кучу изображений, вы должны определить свою собственную очередь, чтобы сделать изменения размера:

MBProgressHUD *HUD = [self showHUD]; 

NSOperationQueue *resizeQueue = [[NSOperationQueue alloc] init]; 
resizeQueue.maxConcurrentOperationCount = 1; 

NSOperation *completeOperation = [NSBlockOperation blockOperationWithBlock:^{ 

    //when done, hide the HUD (using the main queue) 

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
     [self hideHUD:HUD]; 
    }]; 
}]; 

for (NSInteger i = 0; i < imageCount; i++) 
{ 
    NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ 
     // do your image resizing here 
    }]; 

    // make the completion operation dependent upon each image resize operation 

    [completionOperation addDependency:operation]; 

    // queue the resize operation 

    [resizeQueue addOperation:operation]; 
} 

// when all done, queue the operation that will remove the HUD 

[resizeQueue addOperation:completionOperation]; 

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

+0

Спасибо, Роб, только одно изображение. Оба ответа верны для этого, поэтому я принял другого и проголосовал за это. Если вы не видите какой-либо причины, почему первый подход будет отличаться/не работать одинаково. Спасибо – StuartM

+0

@StuartM С точки зрения ответа, вы принимаете, без обид. С точки зрения использования GCD и 'performSelectorInBackground', в настоящее время GCD (например, очереди отправки) или очереди операций предпочтительнее традиционных подходов к потоку, таких как' performSelectorInBackground'. См. [Руководство по программированию параллелизма] (https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html). – Rob

+0

Спасибо, Роб, всегда цените свои знания! – StuartM

Смежные вопросы