2012-04-10 35 views
1

我有一個博客應用程序,我正在製作。要撰寫新條目,有一個「撰寫條目」視圖,用戶可以選擇照片並輸入文本。對於照片,有一個UIImageView佔位符,點擊此按鈕後,自定義ImagePicker出現,用戶可以選擇最多3張照片。調整ALAsset照片需要很長時間。任何方式在這個?

這就是問題出現的地方。我不需要ALAsset的全分辨率照片,但同時縮略圖的分辨率也太低,無法使用。

所以我現在在做的是將全分辨率照片調整到更小的尺寸。但是,這需要一些時間,尤其是在將3張照片調整爲較小尺寸時。

這裏是剪斷顯示我在做什麼代碼:

ALAssetRepresentation *rep = [[dict objectForKey:@"assetObject"] defaultRepresentation]; 

    CGImageRef iref = [rep fullResolutionImage]; 
    if (iref) 
    { 
     CGRect screenBounds = [[UIScreen mainScreen] bounds]; 

     UIImage *previewImage; 
     UIImage *largeImage; 

     if([rep orientation] == ALAssetOrientationUp) //landscape image 
     { 
      largeImage = [[UIImage imageWithCGImage:iref] scaledToWidth:screenBounds.size.width]; 
      previewImage = [[UIImage imageWithCGImage:iref] scaledToWidth:300]; 
     } 
     else // portrait image 
     { 
      previewImage = [[[UIImage imageWithCGImage:iref] scaledToHeight:300] imageRotatedByDegrees:90]; 
      largeImage = [[[UIImage imageWithCGImage:iref] scaledToHeight:screenBounds.size.height] imageRotatedByDegrees:90]; 
     } 
    } 

這裏,從全分辨率圖像,我創建了兩個圖像:一個預覽圖像(在長端最大300像素)和大圖像(最長960像素或640像素)。預覽圖像是「新條目」預覽中應用程序本身顯示的內容。大圖像是上傳到服務器時將使用的圖像。

我使用來調整實際的代碼,我從什麼地方抓起這裏:

-(UIImage*)scaledToWidth:(float)i_width 
{ 
    float oldWidth = self.size.width; 
    float scaleFactor = i_width/oldWidth; 

    float newHeight = self.size.height * scaleFactor; 
    float newWidth = oldWidth * scaleFactor; 

    UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight)); 
    [self drawInRect:CGRectMake(0, 0, newWidth, newHeight)]; 
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();  
    UIGraphicsEndImageContext(); 
    return newImage; 
} 

我錯了在這裏做的事情?就目前而言,ALAsset縮略圖的清晰度太低,與此同時,我不需要整個完整的分辨率。現在都在工作,但調整大小需要一些時間。這只是一個必要的結果嗎?

謝謝!

回答

3

這是調整圖像大小的必要結果,它需要一些時間。多少取決於設備,資產的分辨率和資產的格式。但是你沒有任何控制權。但是您可以控制調整大小的位置。我懷疑現在你正在調整主線程中的圖像大小,這會導致UI在你調整大小的時候停下來。做足夠的圖像,你的應用程序將顯示掛起足夠長的時間,以便用戶可以關閉並執行其他操作(也許可以查看App Store中的競爭應用程序)。

你應該做的是執行調整主線程的大小。在iOS 4及更高版本中,這變得更簡單了,因爲您可以使用Grand Central Dispatch來調整大小。你可以從上面把你原來的代碼塊,並在這樣的塊包裝它:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 
    ALAssetRepresentation *rep = [[dict objectForKey:@"assetObject"] defaultRepresentation]; 

    CGImageRef iref = [rep fullResolutionImage]; 
    if (iref) 
    { 
     CGRect screenBounds = [[UIScreen mainScreen] bounds]; 

     __block UIImage *previewImage; 
     __block UIImage *largeImage; 

     if([rep orientation] == ALAssetOrientationUp) //landscape image 
     { 
      largeImage = [[UIImage imageWithCGImage:iref] scaledToWidth:screenBounds.size.width]; 
      previewImage = [[UIImage imageWithCGImage:iref] scaledToWidth:300]; 
     } 
     else // portrait image 
     { 
      previewImage = [[[UIImage imageWithCGImage:iref] scaledToHeight:300] imageRotatedByDegrees:90]; 
      largeImage = [[[UIImage imageWithCGImage:iref] scaledToHeight:screenBounds.size.height] imageRotatedByDegrees:90]; 
     } 
     dispatch_async(dispatch_get_main_queue(), ^{ 
     // do what ever you need to do in the main thread here once your image is resized. 
     // this is going to be things like setting the UIImageViews to show your new images 
     // or adding new views to your view hierarchy 
     }); 
    } 
}); 

你必須思考的東西有點不同這種方式。例如,您現在已經將以前單步執行的步驟分解爲多個步驟。在此之後運行的代碼將在圖像調整大小完成之前或者在您對圖像執行任何操作之前結束運行,因此您需要確保沒有任何與這些圖像的依賴關係,否則您可能會崩潰。

2

一個遲到的答案,但對於這個問題的絆腳石,你可能要考慮使用fullScreenImage而不是defaultRepresentationfullResolutionImage。它通常要小得多,但仍然足夠大以保持較大縮略圖的良好質量。

+0

老兄,你是個天才:) – Stavash 2015-06-17 07:34:34