How to draw a shape on top of a UIImage while respecting the image's alpha mask

前端 未结 4 1602
隐瞒了意图╮
隐瞒了意图╮ 2021-01-31 12:29

I need a UIImageView that can draw itself in color or b/w according to a flag:

  BOOL isGrey;

I\'m trying to do it by drawing a black rectangle

相关标签:
4条回答
  • 2021-01-31 13:06

    Although it doesn't directly answer your question, you may be able to get the effect you are looking for by using the kCGBlendModeLuminosity blend mode:

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

    Also, the rect passed to drawRect: is the invalid area, not the entire area. You should be using the bounds instead

    0 讨论(0)
  • 2021-01-31 13:18

    You could try to add a mask to the view's Core Animation layer.

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

    One other thought. Why can't you just create a b&w version of the image and swap that out depending on your flag?

    0 讨论(0)
  • 2021-01-31 13:19

    I'd take the easy way out and draw a black circle with the same size as the round image you have. Probably not what you are asking for.

    0 讨论(0)
  • 2021-01-31 13:21

    To draw a shape while respecting an image's alpha mask, just add one line before you draw:

     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 讨论(0)
提交回复
热议问题