【问题标题】:Showing a HUD whilst an image is downscaled in size在缩小图像尺寸时显示 HUD
【发布时间】:2013-12-27 07:22:22
【问题描述】:

我有一个应用程序,用户使用相机拍照,然后选择使用照片。调用以下方法:

- (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在主线程上更新,我是否也可以在这里考虑线程。我不确定何时确定某些部分是否应该在不同的线程上?

【问题讨论】:

    标签: ios ios6 uiview uiimagepickercontroller hud


    【解决方案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 调整为您想要的任何值。坦率地说,考虑到这样做的全部意义在于您希望缩小大图像,您可能不想同时运行太多(因为内存使用问题),但这是一种选择。

    【讨论】:

    • 谢谢 Rob,只有一张图片。这两个答案都是正确的,所以我接受了另一个答案并投了赞成票。除非您看到第一种方法不同/不以相同方式工作的任何原因。谢谢
    • @StuartM 就您接受的答案而言,没有冒犯。在使用 GCD 与 performSelectorInBackground 方面,现在 GCD(又名调度队列)或操作队列将优于传统的线程方法,例如 performSelectorInBackground。见Concurrency Programming Guide
    • 感谢 Rob,永远感谢您的知识!
    【解决方案2】:

    像这样在后台线程中调用缩放方法:

    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];
    }
    

    【讨论】:

    • 如果你使用performSelectorInBackground,我相信你应该为那个新线程定义@autoreleasepool
    猜你喜欢
    • 2016-04-05
    • 1970-01-01
    • 2016-10-29
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    相关资源
    最近更新 更多