Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is that possible to change the color for an image programmatically?

I am working an app which has different theme color, but i don't want to have too much image assets in the project (basically don't want to make the project size too big), is that possible to use one image but different colors?

Thanks!

like image 391
user3288387 Avatar asked Feb 14 '14 05:02

user3288387


2 Answers

I agree with Matt, you should check CIFilter for future image modification. but if you are looking for a quick code sample, here is how i did it. works pretty fine for me, simply need to call like this :

 [self useColor:[UIColor redColor] forImage:WHATEVER_IMAGE];

 - (UIImage *)useColor:(UIColor *)color forImage:(UIImage *)image
 {
     if(!color)
         return image;

     NSUInteger width = CGImageGetWidth([image CGImage]);
     NSUInteger height = CGImageGetHeight([image CGImage]);
     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

     NSUInteger bytesPerPixel = 4;
     NSUInteger bytesPerRow = bytesPerPixel * width;
     NSUInteger bitsPerComponent = 8;
     NSUInteger bitmapByteCount = bytesPerRow * height;

     unsigned char *rawData = (unsigned char*) calloc(bitmapByteCount, sizeof(unsigned char));

     CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                             bitsPerComponent, bytesPerRow, colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
     CGColorSpaceRelease(colorSpace);

     CGContextDrawImage(context, CGRectMake(0, 0, width, height), [image CGImage]);

     CGColorRef cgColor = [color CGColor];
     const CGFloat *components = CGColorGetComponents(cgColor);
     float r = components[0] * 255.0;
     float g = components[1] * 255.0;
     float b = components[2] * 255.0;
     //float a = components[3]; // not needed

     int byteIndex = 0;

     while (byteIndex < bitmapByteCount)
     {
         int oldR = rawData[byteIndex];
         int oldG = rawData[byteIndex + 1];
         int oldB = rawData[byteIndex + 2];
         int oldA = rawData[byteIndex + 3];
         if(oldR != 0 || oldG != 0 || oldB != 0 || oldA != 0)
         {
             rawData[byteIndex] = r;
             rawData[byteIndex + 1] = g;
             rawData[byteIndex + 2] = b;
         }

         byteIndex += 4;
     }

     UIImage *result = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context) scale:image.scale orientation:image.imageOrientation];

     CGContextRelease(context);
     free(rawData);

     return result;
 }
like image 187
Xu Yin Avatar answered Oct 24 '22 22:10

Xu Yin


You can modify the colors of an image in interesting ways programmatically using CIFilter, if that's what you're asking.

Take a stroll through the catalog... https://developer.apple.com/library/ios/documentation/graphicsimaging/reference/CoreImageFilterReference/Reference/reference.html#//apple_ref/doc/uid/TP40004346

like image 25
matt Avatar answered Oct 24 '22 21:10

matt