2013-12-09 48 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 vs'performSelectorInBackground'方面,現在GCD(aka dispatch queues)或操作隊列將優於傳統的線程方法,比如'performSelectorInBackground'。請參閱[併發編程指南](https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html)。 – Rob

+0

感謝羅布,永遠感謝您的知識! – StuartM