2009-08-28 41 views
9

Tôi cần một UIImageView có thể vẽ bản thân trong màu hoặc b/w theo một lá cờ:Làm thế nào để vẽ một hình trên một UIImage đồng thời tôn trọng alpha của hình ảnh mặt nạ

BOOL isGrey; 

Tôi đang cố gắng để làm điều đó bằng cách vẽ một hình chữ nhật màu đen trên đầu trang của hình ảnh ban đầu với Quartz blendmode thiết lập để màu. Điều này làm việc ngoại trừ nó không tôn trọng mặt nạ alpha của hình ảnh.

Xem hình minh họa: alt text http://img214.imageshack.us/img214/1407/converttogreyscaleillo.png

tìm kiếm Google và SO, tôi thấy và thử nhiều giải pháp nhưng không ai tôn trọng các mặt nạ một trong hai.

Dưới đây là đoạn code mà tạo ra 'Những gì tôi có được' hình trên:

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

Có một số bản vẽ chế độ thạch anh mà tôi quên để thiết lập? Tôi đã xem qua hướng dẫn lập trình thạch anh nhưng rất khó để trích xuất một chút thông tin bạn cần từ các đối tượng chồng chéo và siêu liên kết.

Rõ ràng là tôi đang tìm một giải pháp chung sẽ áp dụng cho hình ảnh với bất kỳ hình dạng mặt nạ nào, không chỉ vòng tròn được hiển thị.

Trả lời

10

Để vẽ một hình dạng trong khi tôn trọng mặt nạ alpha của hình ảnh, chỉ cần thêm một dòng trước khi bạn vẽ:

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

Ngoại trừ việc điều này không hoạt động nếu chế độ xem của bạn backgroundColor là UIColor clearColor. –

1

Mặc dù nó không trực tiếp trả lời câu hỏi của bạn, bạn có thể để có được hiệu ứng bạn đang tìm kiếm bằng cách sử dụng chế độ pha trộn 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]); 
} 

Ngoài ra, rect truyền cho drawRect: được vùng không hợp lệ, không phải toàn bộ khu vực. Bạn nên sử dụng số bounds thay vì

+0

Bạn thử này? Bởi vì nó mang lại cho tôi những kết quả không chính xác giống như tất cả những thứ khác mà tôi đã thử. – willc2

+0

Dường như - [UIImage drawInRect:] không tính đến chế độ hòa trộn được đặt trên CGContext. Tôi đã cập nhật câu trả lời của mình để sử dụng CGContextDrawImage thay thế - đã thử nghiệm và làm việc :) – rpetrich

+0

Bạn đã thử hình ảnh này với một kênh alpha, với nền màu clearColor hoặc UIImageView không mờ đục? Mã của bạn hoạt động trên hình ảnh không bị che khuất hoặc các imageView có màu bg mờ hoặc imageViews thuộc tính Opaque = YES. Nếu hình ảnh giống như quả bóng màu xanh lá cây trong ví dụ của tôi, màu sắc không thay đổi thành màu xám. – willc2

0

Bạn có thể thử thêm mặt nạ vào lớp Hình ảnh động của chế độ xem.

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

Một suy nghĩ khác. Tại sao bạn không thể tạo một phiên bản b & w của hình ảnh và hoán đổi tùy theo cờ của bạn?

+1

Vì tôi muốn tìm hiểu cách giải quyết vấn đề chung về việc vẽ hình ảnh trong khi tôn trọng kênh alpha hiện có. Bạn có biết làm thế nào để làm điều đó? – willc2

+0

Tôi hiểu. Có vẻ hợp lý. Tôi không biết làm thế nào để làm điều đó mà không làm một số nghiên cứu. Lấy làm tiếc. –

+0

sử dụng chế độ đa pha trộn ... chỉ cần đoán – dontWatchMyProfile

1

Tôi muốn lấy một cách dễ dàng và vẽ một vòng tròn màu đen có cùng kích thước với hình ảnh tròn mà bạn có. Có lẽ không phải những gì bạn đang yêu cầu.

Các vấn đề liên quan