2009-10-20 79 views
3

我想重新創建UITabBarController對標籤欄中的圖像使用完全相同圖像的效果。我用一些掩飾來解決一些想法,但是我還沒有得到任何令人滿意的結果。UITabBarController-like image masking effect

任何人都有這樣做的食譜?

回答

0

Three20有一個類用於掩蓋圖像。你想要TTMaskStyle。你可以試着拿出源代碼,或者只是複製邏輯,但它應該適合你。您可以在TTCatalog示例應用程序中找到示例。

+0

謝謝......我在使用320代碼時遇到了一些困難,但我會在週末將它分開,看看它是如何工作的(並在此處發佈) – dpjanes 2009-10-22 20:46:54

2

Three20的東西沒有太多幫助,但經過幾個小時的黑客攻擊後,我想出了一個令人滿意的解決方案。兩大核心技巧需要知道是:

  • 如何將圖像轉換爲 DeviceGray色彩空間
  • 如何屏蔽圖像

評論是內嵌代碼:

+ (UIImage*) tabBarLikeIconWith:(UIImage*)tabBarIconImage 
{ 
/* 
* 1. 
* The output is going to be an image the exact same size as the tabBarIconImage 
*/ 
CGSize size = CGSizeMake(tabBarIconImage.size.width, tabBarIconImage.size.height); 
CGRect bounds = CGRectMake(0, 0, tabBarIconImage.size.width, tabBarIconImage.size.height); 

/* 
* 2. 
* The background image is a fairly big (50x50) image used to create whatever gradient 
* effect is desired for the final image. We clip & move the image to proper size. 
* 
* This could probably be cleverly composed on the fly using Quartz functions too. 
*/ 
static UIImage* backgroundImage = nil; 
if (backgroundImage == nil) { 
    backgroundImage = [UIImage imageNamed:@"TabBarLikeTransition.png"]; 
} 

UIGraphicsBeginImageContext(size); 
[backgroundImage drawAtPoint:CGPointMake((size.width - backgroundImage.size.width)/2, (size.height - backgroundImage.size.height)/2)]; 

UIImage* workingBackgroundImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

/* 
* 3. 
* We cannot deal with alpha levels in the tabBarIconImage, so we composite 
* it with a white background to get a solid image. 
*/ 
UIGraphicsBeginImageContext(size); 

[[UIColor whiteColor] set]; 
UIRectFill(bounds); 
[tabBarIconImage drawAtPoint:CGPointMake(0, 0)]; 

UIImage* maskImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

/* 
* 4. 
* Next we convert the maskImage to the 'DeviceGray' colorspace 
* needed by Apple's masking functions. Why this isn't done automatically 
* is something of a mystery to me. 
*/ 
CGColorSpaceRef grayscaleColorSpace = CGColorSpaceCreateDeviceGray(); 
CGContextRef bitmapContext = CGBitmapContextCreate(NULL, 
              size.width, 
              size.height, 
              8, 
              8 * size.width, 
              grayscaleColorSpace, 
              0 
              ); 

CGContextDrawImage(bitmapContext, bounds, maskImage.CGImage); 
CGImageRef maskImageRef = CGBitmapContextCreateImage(bitmapContext); 

maskImage = [UIImage imageWithCGImage:maskImageRef]; 

CGContextRelease(bitmapContext); 
CGImageRelease(maskImageRef); 
CGColorSpaceRelease(grayscaleColorSpace); 

/* 
* 5. 
* Mask the background and our new grayscale mask and we're off the races. 
* I'd probably clean up these variables names if I had free time. 
* 
* This cleverness comes from here: 
* http://iosdevelopertips.com/cocoa/how-to-mask-an-image.html 
*/ 
CGImageRef maskRef = maskImage.CGImage; 
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef), 
            CGImageGetHeight(maskRef), 
            CGImageGetBitsPerComponent(maskRef), 
            CGImageGetBitsPerPixel(maskRef), 
            CGImageGetBytesPerRow(maskRef), 
            CGImageGetDataProvider(maskRef), NULL, true); 

CGImageRef masked = CGImageCreateWithMask([workingBackgroundImage CGImage], mask); 

CGImageRelease(mask); 

return [UIImage imageWithCGImage:masked]; 
}