static inline uint8_t clamp(uint8_t a, uint8_t b) {
int16_t newval = (int32_t) a - b;
if (newval > 255)
return 255;
if (newval < 0)
return 0;
return newval;
}
void saturation(uint8_t *data, int width, int height, float value) {
uint16_t v = value ;
for (int i = 0; i < width * height * 4; i += 4) {
uint8_t r = data[i + 0];
uint8_t g = data[i + 1];
uint8_t b = data[i + 2];
uint8_t avg = (int16_t) (r + g + b) / 3;
uint8_t rr = clamp(r, avg);
uint8_t gg = clamp(g, avg);
uint8_t bb = clamp(b, avg);
data[i + 0] = rr * v + avg;
data[i + 1] = gg * v + avg;
data[i + 2] = bb * v + avg;
}
}
exmple:
NSInteger theWidth = (NSInteger)srcImg.size.width;
// apply blending effect
unsigned char *rawData = malloc(theWidth * theWidth * 4);
CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
CGRect theFrame = CGRectMake(0.0, 0.0, srcImg.size.width, srcImg.size.height);
CGContextRef context = CGBitmapContextCreate(rawData, theWidth, theWidth, 8, theWidth * 4, cs, kCGImageAlphaNoneSkipLast);
CGColorSpaceRelease(cs);
UIImage *sat_image = srcImg;
// draw image first
CGContextDrawImage(context, theFrame, sat_image.CGImage);
saturation(rawData, theWidth, theWidth, 0.16);// save final image
CGImageRef finalImage = CGBitmapContextCreateImage(context);
// release resouces
UIImage *result = [UIImage imageWithCGImage:finalImage];
CGContextRelease(context);
CGImageRelease(finalImage);
//CGImageRelease(firstStageImage);
free(rawData);