我正在使用具有不同主题颜色的应用程序,但我不希望在项目中有太多图像资源(基本上不希望使项目大小太大),是否可以使用一个图像但不同的颜色?
谢谢!
答案 0 :(得分:6)
您可以使用CIFilter以编程方式以有趣的方式修改图像的颜色,如果这就是您所要求的。
答案 1 :(得分:6)
我同意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;
}
答案 2 :(得分:0)
一个更简单的答案:如果您的图像可以是单个颜色(例如线条图),那么只需指定您想要UIImageRenderingModeAlwaysTemplate。现在图像将采用其容器的tintColor
,因此您只需更改tintColor
即可更改其颜色。
答案 3 :(得分:0)
基于Xu Yin's answer - 一个更适合 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;
}