iOS: Applying a RGB filter to a greyscale PNG

后端 未结 3 1377
抹茶落季
抹茶落季 2020-12-14 13:17

I have a greyscale gem top view.

(PNG format, so has alpha component)

相关标签:
3条回答
  • 2020-12-14 14:11

    The easiest way to do it is to draw the image into an RGB-colorspaced CGBitmapContext, use CGContextSetBlendMode to set kCGBlendModeColor, and then draw over it with a solid color (e.g. with CGContextFillRect).

    0 讨论(0)
  • 2020-12-14 14:13

    The best looking results are going to come from using the gray value to index into a gradient that goes from the darkest to the lightest colors of the desired result. Unfortunately I don't know the specifics of doing that with core graphics.

    0 讨论(0)
  • 2020-12-14 14:15

    This is an improvement upon the answer in the question and an implementation of @Anomie

    First, put this at the beginning of your UIButton class, or your view controller. It translates from UIColor to an RGBA value, which you will need later.

    typedef enum { R, G, B, A } UIColorComponentIndices;
    
    
    @implementation UIColor (EPPZKit)
    
    - (CGFloat)redRGBAValue {
        return CGColorGetComponents(self.CGColor)[R];
    }
    
    - (CGFloat)greenRGBAValue  {
        return CGColorGetComponents(self.CGColor)[G];
    }
    
    - (CGFloat)blueRGBAValue  {
        return CGColorGetComponents(self.CGColor)[B];
    }
    
    - (CGFloat)alphaRGBAValue  {
        return CGColorGetComponents(self.CGColor)[A];
    }
    
    @end
    

    Now, make sure that you have your custom image button in IB, with a grayscale image and the right frame. This is considerably better and easier then creating the custom image button programmatically, because:

    • you can let IB load the image, instead of having to load it manually
    • you can adjust the button and see it visually in IB
    • your IB will look more like your app at runtime
    • you don't have to manually set frames

    Assuming you are having the button be in IB (near the bottom will be support for having it programmatically created), add this method to your view controller or button cub class:

    - (UIImage*)customImageColoringFromButton:(UIButton*)customImageButton fromColor:(UIColor*)color {
        UIImage *customImage = [customImageButton.imageView.image copy];
    
        UIGraphicsBeginImageContext(customImageButton.imageView.frame.size); {
            CGContextRef X = UIGraphicsGetCurrentContext();
    
            [customImage drawInRect: customImageButton.imageView.frame];
    
            // Overlay a colored rectangle
            CGContextSetBlendMode( X, kCGBlendModeColor) ;
            CGContextSetRGBFillColor ( X, color.redRGBAValue, color.greenRGBAValue, color.blueRGBAValue, color.alphaRGBAValue);
            CGContextFillRect ( X, customImageButton.imageView.frame);
    
            // Redraw
            [customImage drawInRect:customImageButton.imageView.frame blendMode: kCGBlendModeDestinationIn alpha: 1.0];
    
            customImage = UIGraphicsGetImageFromCurrentImageContext();
        }
        UIGraphicsEndImageContext();
    
        return customImage;
    }
    

    You then will need to call it in a setup method in your view controller or button subclass, and set the imageView of the button to it:

    [myButton.imageView setImage:[self customImageColoringFromButton:myButton fromColor:desiredColor]];
    

    If you are not using IB to create the button, use this method:

    - (UIImage*)customImageColoringFromImage:(UIImage*)image fromColor:(UIColor*)color fromFrame:(CGRect)frame {
        UIImage *customImage = [image copy];
    
        UIGraphicsBeginImageContext(frame.size); {
            CGContextRef X = UIGraphicsGetCurrentContext();
    
            [customImage drawInRect: frame];
    
            // Overlay a colored rectangle
            CGContextSetBlendMode( X, kCGBlendModeColor) ;
            CGContextSetRGBFillColor ( X, color.redRGBAValue, color.greenRGBAValue, color.blueRGBAValue, color.alphaRGBAValue);
            CGContextFillRect ( X, frame);
    
            // Redraw
            [customImage drawInRect:frame blendMode: kCGBlendModeDestinationIn alpha: 1.0];
    
            customImage = UIGraphicsGetImageFromCurrentImageContext();
        }
        UIGraphicsEndImageContext();
    
        return customImage;
    }
    

    And call it with:

    [self.disclosureButton.imageView setImage:[self customImageColoringFromImage:[UIImage imageNamed:@"GemTop_Dull.png"] fromColor:desiredColor fromFrame:desiredFrame]];
    
    0 讨论(0)
提交回复
热议问题