How can I change the saturation of an UIImage?

后端 未结 6 1548
旧巷少年郎
旧巷少年郎 2021-01-30 05:42

I have an UIImage and want to shift it\'s saturation about +10%. Are there standard methods or functions that can be used for this?

6条回答
  •  栀梦
    栀梦 (楼主)
    2021-01-30 06:22

    Starting with a View-based Application Template, create a new subclass of UIView like so:

    // header file
    @interface DesatView : UIView {
         UIImage *image;
         float saturation;
    }
    @property (nonatomic, retain) UIImage *image;
    @property (nonatomic) float desaturation;
    @end  
    
    // implementation file
    #import "DesatView.h"
    @implementation DesatView
    @synthesize image, desaturation;
    
    -(void)setSaturation:(float)sat;
        {
            saturation = sat;
            [self setNeedsDisplay];
        }
    
    - (id)initWithFrame:(CGRect)frame {
         if (self = [super initWithFrame:frame]) {
              self.backgroundColor = [UIColor clearColor]; // else background is black
              desaturation = 0.0; // default is no effect
         }
         return self;
    }
    
    - (void)drawRect:(CGRect)rect {
         CGContextRef context = UIGraphicsGetCurrentContext();
         CGContextSaveGState(context);
    
         CGContextTranslateCTM(context, 0.0, self.bounds.size.height); // flip image right side up
         CGContextScaleCTM(context, 1.0, -1.0);
    
         CGContextDrawImage(context, rect, self.image.CGImage);
         CGContextSetBlendMode(context, kCGBlendModeSaturation);
         CGContextClipToMask(context, self.bounds, image.CGImage); // restricts drawing to within alpha channel
         CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, desaturation);
         CGContextFillRect(context, rect);
    
         CGContextRestoreGState(context); // restore state to reset blend mode
    }
    @end
    

    Now in your view controller's viewDidLoad method, put the view on screen and set it's saturation like this:

    - (void)viewDidLoad {
        [super viewDidLoad];  
    
        DesatView *dv = [[DesatView alloc] initWithFrame:CGRectZero];
        dv.image = [UIImage imageNamed:@"someImage.png"];
        dv.frame = CGRectMake(0, 0, dv.image.size.width, dv.image.size.height);
        dv.center = CGPointMake(160, 240); // put it mid-screen
        dv.desaturation = 0.2; // desaturate by 20%,
    
        [self.view addSubview:dv];  // put it on screen   
    }  
    

    Change the saturation like this:

     dv.saturation = 0.8; // desaturate by 80%  
    

    Obviously if you want to use it outside of a single method, you should make dv an ivar of the view controller. Hope this helps.

提交回复
热议问题