2009-08-28 13 views
9

我需要一個UIImageView,可以自行繪製的顏色或b /根據標誌寬:如何繪製形狀上一個UIImage的頂部,同時尊重圖像的alpha掩蓋

BOOL isGrey; 

我想通過在Quartz blendmode設置爲Color的原始圖像頂部繪製黑色矩形來實現。這個工作除了不尊重圖像的alpha蒙版。

見圖示: alt text http://img214.imageshack.us/img214/1407/converttogreyscaleillo.png

搜索谷歌和SO,我發現並試圖幾種解決方案,但沒有任何尊重的面具。

這裏是產生上述的「我所得到的」形象代碼:

- (void)drawRect:(CGRect)rect { 

    if (isGrey) { 
     CGContextRef context = UIGraphicsGetCurrentContext(); 

     // flip orientation 
     CGContextTranslateCTM(context, 0, self.bounds.size.height); 
     CGContextScaleCTM(context, 1.0, -1.0); 

     // draw the image 
     CGContextDrawImage(context, self.bounds, self.image.CGImage); 

     // set the blend mode and draw rectangle on top of image 
     CGContextSetBlendMode(context, kCGBlendModeSaturation); 
     CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0); 
     CGContextFillRect(context, rect);  
    } else { 
     [self.image drawInRect:rect]; 
    } 
} 

有沒有辦法,我忘記設置一些石英繪圖模式?我已經看過Quartz編程指南,但很難從重疊和超鏈接主題中提取您需要的信息。

很顯然,我希望能夠找到適用於圖像與任何蒙面形狀,不只是顯示的圓一個通用的解決方案。

回答

10

要繪製形狀,同時尊重圖像的alpha遮罩,只需添加一行在繪製之前:

CGContextClipToMask(context, self.bounds, image.CGImage); 

// example usage 
    - (void)drawRect:(CGRect)rect { 

    if (isGrey) { 
      CGContextRef context = UIGraphicsGetCurrentContext(); 

      // flip orientation 
      CGContextTranslateCTM(context, 0.0, self.bounds.size.height); 
      CGContextScaleCTM(context, 1.0, -1.0); 

      // draw the image 
      CGContextDrawImage(context, self.bounds, self.image.CGImage); 

      // set the blend mode and draw rectangle on top of image 
      CGContextSetBlendMode(context, kCGBlendModeColor); 
      CGContextClipToMask(context, self.bounds, image.CGImage); // respect alpha mask 
      CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0); 
      CGContextFillRect(context, rect);    
    } else { 
      [self.image drawInRect:rect]; 
    } 

}

+0

除了這不工作,如果你的觀點backgroundColor是UIColor clearColor。 – 2011-06-10 21:20:45

1

雖然它並不直接回答你的問題,你可以讓你通過使用kCGBlendModeLuminosity混合模式尋找效果:

- (void)drawRect:(CGRect)rect { 
    CGSize imageSize = [image size]; 
    CGContextRef c = UIGraphicsGetCurrentContext(); 
    if (isGrey) 
     CGContextSetBlendMode(c, kCGBlendModeLuminosity); 
    CGContextScaleCTM(c, 1.0, -1.0); 
    CGContextDrawImage(c, CGRectMake(0.0f, 0.0f, imageSize.width, -imageSize.height), [image CGImage]); 
} 

另外,RECT傳遞給drawRect:是無效區域,而不是整個區域。您應該使用bounds而不是

+0

你試試這個?因爲它給了我和我嘗試過的所有其他事情一樣的錯誤結果。 – willc2 2009-08-28 18:21:48

+0

看來 - [UIImage drawInRect:]沒有考慮在CGContext上設置的混合模式。我已經更新了我的答案,使用CGContextDrawImage代替 - 經過測試並正在工作:) – rpetrich 2009-08-31 09:35:11

+0

您是否在Alpha通道的圖像上使用clearColor backgroundColor或非透明UIImageView嘗試此操作?您的代碼適用於非屏蔽圖像,或具有不透明bg顏色的imageView或不透明屬性= YES的imageViews。如果圖像與我例子中的綠球相似,則顏色不會更改爲灰度。 – willc2 2009-09-01 03:09:46

0

您可以嘗試向視圖的Core Animation圖層添加遮罩。

CALayer *maskLayer = [CALayer layer]; 
[maskLayer setBounds:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f)]; 

// Center the layer 
[maskLayer setPosition:CGPointMake([self view].bounds.size.width/2, 
          [self view].bounds.size.height/2)]; 

// Set the cornerRadius to half the width/height to get a circle. 
[maskLayer setCornerRadius:50.f]; 
[maskLayer setMasksToBounds:YES]; 

// Any solid color will do. Just using black here. 
[maskLayer setBackgroundColor:[[UIColor blackColor] CGColor]]; 

// Set the mask which will only allow that which is in the 
// circle show through 
[[[self view] layer] setMask:maskLayer]; 

另一個想法。爲什麼你不能只創建一個b版本的圖像並根據你的標誌交換出來?

+1

因爲我想要學習如何解決繪製圖像的一般問題,同時尊重現有的alpha通道。你知道怎麼做嗎? – willc2 2009-08-28 18:16:45

+0

我明白了。看起來很合理。如果不做一些研究,我不知道該怎麼做。抱歉。 – 2009-08-29 02:57:06

+0

使用乘法混合模式...只是一個猜測 – dontWatchMyProfile 2010-04-05 13:33:51

1

我會採取簡單的方法,並繪製一個與您的圓形圖像尺寸相同的黑色圓圈。可能不是你要求的。