我正在开发一款应用程序,它有不同的主题颜色,但我不想在项目中使用过多的图像资源(基本上不想让项目大小变得太大),那么是否有可能使用一张图片但不同的颜色呢?
谢谢!
我正在开发一款应用程序,它有不同的主题颜色,但我不想在项目中使用过多的图像资源(基本上不想让项目大小变得太大),那么是否有可能使用一张图片但不同的颜色呢?
谢谢!
我同意Matt的观点,你应该考虑使用CIFilter进行未来的图像修改。但如果你正在寻找一个快速的代码示例,以下是我是如何做到的。对我来说效果非常好,只需要这样调用:
[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;
}
UIImageRenderingModeAlwaysTemplate
。现在,图像将采用其容器的tintColor
,因此您只需更改tintColor
即可更改其颜色。基于徐寅的回答 - 一个更适合具有圆形图案的SVG图标的版本(因此可能会被代码的原始版本像素化)。
改变只是使用(通过乘法)当前alpha级别对每个像素值进行操作。
- (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;
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 * (oldA / 255.0);
rawData[byteIndex + 1] = g * (oldA / 255.0);
rawData[byteIndex + 2] = b * (oldA / 255.0);
}
byteIndex += 4;
}
UIImage *result = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context) scale:image.scale orientation:image.imageOrientation];
CGContextRelease(context);
free(rawData);
return result;
}