Last active
May 24, 2021 08:28
-
-
Save robertmryan/b89cf29a4b4e69abb02fcfd6640bef51 to your computer and use it in GitHub Desktop.
Objective-C rendition of pixel processing found in http://stackoverflow.com/a/31661519/1271826
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (void)viewDidLoad { | |
[super viewDidLoad]; | |
UIImage *image = [UIImage imageNamed:@"test.png"]; | |
self.imageView.image = [self blackAndWhiteFromImage:image]; | |
} | |
- (UIImage * _Nullable)makeBlackPixelsRedInImage:(UIImage *)image { | |
UInt32 black = [self pixelFromRed:0 green:0 blue:0 alpha:255]; | |
UInt32 red = [self pixelFromRed:255 green:0 blue:0 alpha:255]; | |
return [self processPixelsInImage:image processor:^(UInt32 pixel) { | |
return pixel == black ? red : pixel; | |
}]; | |
} | |
- (UIImage * _Nullable)blackAndWhiteFromImage:(UIImage *)image { | |
return [self processPixelsInImage:image processor:^(UInt32 pixel) { | |
UInt8 red = [self redFromPixel:pixel]; | |
UInt8 green = [self greenFromPixel:pixel]; | |
UInt8 blue = [self blueFromPixel:pixel]; | |
UInt8 alpha = [self alphaFromPixel:pixel]; | |
UInt8 luminance = (UInt8)(0.2126 * red + 0.7152 * green + 0.0722 * blue); | |
return [self pixelFromRed:luminance green:luminance blue:luminance alpha:alpha]; | |
}]; | |
} | |
- (UIImage * _Nullable)processPixelsInImage:(UIImage *)inputImage processor:(UInt32 (^)(UInt32))processor { | |
CGImageRef inputCGImage = inputImage.CGImage; | |
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); | |
size_t width = CGImageGetWidth(inputCGImage); | |
size_t height = CGImageGetHeight(inputCGImage); | |
NSInteger bytesPerPixel = 4; | |
NSInteger bitsPerComponent = 8; | |
NSInteger bytesPerRow = bytesPerPixel * width; | |
uint32_t bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Little; | |
CGContextRef context = CGBitmapContextCreate(nil, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo); | |
CGColorSpaceRelease(colorSpace); | |
if (context == nil) { | |
return nil; | |
} | |
CGContextDrawImage(context, CGRectMake(0, 0, width, height), inputCGImage); | |
UInt32 *pixelBuffer = CGBitmapContextGetData(context); | |
for (NSInteger row = 0; row < height; row++) { | |
for (NSInteger col = 0; col < width; col++) { | |
pixelBuffer[row * width + col] = processor(pixelBuffer[row * width + col]); | |
} | |
} | |
CGImageRef outputCGImage = CGBitmapContextCreateImage(context); | |
UIImage *outputImage = [UIImage imageWithCGImage:outputCGImage scale:inputImage.scale orientation:inputImage.imageOrientation]; | |
CGImageRelease(outputCGImage); | |
CGContextRelease(context); | |
return outputImage; | |
} | |
- (UInt8)redFromPixel:(UInt32)pixel { | |
return (UInt8)((pixel >> 24) & 255); | |
} | |
- (UInt8)greenFromPixel:(UInt32)pixel { | |
return (UInt8)((pixel >> 16) & 255); | |
} | |
- (UInt8)blueFromPixel:(UInt32)pixel { | |
return (UInt8)((pixel >> 8) & 255); | |
} | |
- (UInt8)alphaFromPixel:(UInt32)pixel { | |
return (UInt8)(pixel & 255); | |
} | |
- (UInt32)pixelFromRed:(UInt8)red green:(UInt8)green blue:(UInt8)blue alpha:(UInt8)alpha { | |
return ((UInt32)red << 24) | ((UInt32)green << 16) | ((UInt32)blue << 8) | ((UInt32)alpha << 0); | |
} | |
@end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
`fun replaceColor(backgroundImage: Bitmap?, foregroundImage: Bitmap?, fromColor: Int, targetColor: Int): Bitmap?
{
if (backgroundImage == null || foregroundImage == null)
{
return null
}
// Source image size
var width = backgroundImage.width
var height = backgroundImage.height