我正在制作军事战略游戏。当我的游戏中的一支军队占领一个领土时,我希望能够改变地图上领土的颜色,以便它显示该领土的新控制者。这是我改变领土图像的代码:
我会写这一行,例如:
UIImage *newImg = [self imageOfTerritoryWithNewArmy:@"japan" AndOldTerritoryImage:[UIImage imageNamed:@"ireland.gif"]];
以下是代码的其余部分:
-(UIImage *)createImageWithRGB:(NSArray *)colorData width:(NSInteger)width height:(NSInteger)height{
unsigned char *rawData = malloc(width*height*4);
for (int i=0; i<width*height; ++i)
{
CGFloat red;
CGFloat green;
CGFloat blue;
CGFloat alpha;
UIColor *color = colorData[i];
if ([color respondsToSelector:@selector(getRed:green:blue:alpha:)]) {
[color getRed:&red green:&green blue:&blue alpha:&alpha];
} else {
const CGFloat *components = CGColorGetComponents(color.CGColor);
red = components[0];
green = components[1];
blue = components[2];
alpha = components[3];
}
if(alpha > 0){
rawData[4*i] = red * 255;
rawData[4*i+1] = green * 255;
rawData[4*i+2] = blue * 255;
rawData[4*i+3] = alpha * 255;
}
else{
rawData[4*i] = 255;
rawData[4*i+1] = 255;
rawData[4*i+2] = 255;
rawData[4*i+3] = 0;
}
}
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,
rawData,
width*height*4,
NULL);
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef imageRef = CGImageCreate(width,
height,
8,
32,
4*width,colorSpaceRef,
bitmapInfo,
provider,NULL,NO,renderingIntent);
UIImage *newImage = [UIImage imageWithCGImage:imageRef];
return newImage;
}
- (NSArray *)getRGBAsFromImage:(UIImage*)image atX:(int)xx andY:(int)yy count:(int)count{
NSMutableArray *result = [NSMutableArray arrayWithCapacity:count];
// First get the image into your data buffer
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
// Now your rawData contains the image data in the RGBA8888 pixel format.
int byteIndex = (bytesPerRow * yy) + xx * bytesPerPixel;
for (int ii = 0 ; ii < count ; ++ii)
{
CGFloat red = (rawData[byteIndex] * 1.0) / 255.0;
CGFloat green = (rawData[byteIndex + 1] * 1.0) / 255.0;
CGFloat blue = (rawData[byteIndex + 2] * 1.0) / 255.0;
CGFloat alpha = (rawData[byteIndex + 3] * 1.0) / 255.0;
byteIndex += 4;
UIColor *acolor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
[result addObject:acolor];
}
free(rawData);
return result;
}
-(UIColor *)colorOfArmy:(NSString *)army{
UIColor *color;
army = [army stringByReplacingOccurrencesOfString:@"\a" withString:@""];
if([army isEqual:@"france"]){
color = [[UIColor alloc] initWithRed:0.3137254 green:0.3686274 blue:0.9058823 alpha:1];
}
if([army isEqual:@"germany"]){
color = [[UIColor alloc] initWithRed:0.6352941 green:0.4313725 blue:0.3372549 alpha:1];
}
if([army isEqual:@"uk"]){
color = [[UIColor alloc] initWithRed:0.8941176 green:0.4235294 blue:0.4941176 alpha:1];
}
if([army isEqual:@"italy"]){
color = [[UIColor alloc] initWithRed:0.5137254 green:0.1215686 blue:0.4745098 alpha:1];
}
if([army isEqual:@"ussr"]){
color = [[UIColor alloc] initWithRed:0.3607843 green:0.0823529 blue:0.1215686 alpha:1];
}
if([army isEqual:@"japan"]){
color = [[UIColor alloc] initWithRed:0.9215686 green:0.6156862 blue:0.3137254 alpha:1];
}
if([army isEqual:@""]){
color = [[UIColor alloc] initWithRed:0.1215686 green:0.2823529 blue:0.1607843 alpha:1];
}
if(color == nil){
NSLog(@"the problem was %@", army);
}
return color;
}
-(UIImage *)imageOfTerritoryWithNewArmy:(NSString *)army AndOldTerritoryImage:(UIImage *)oldImg{
CGImageRef image = oldImg.CGImage;
NSInteger width = CGImageGetWidth(image);
NSInteger height = CGImageGetHeight(image);
NSArray *rgba = [self getRGBAsFromImage:oldImg atX:0 andY:0 count:width * height];
NSMutableArray *fixedRGBA = [[NSMutableArray alloc] init];
UIColor *armyColor = [self colorOfArmy:army];
for(UIColor *pixel in rgba){
CGFloat red;
CGFloat green;
CGFloat blue;
CGFloat alpha;
if ([pixel respondsToSelector:@selector(getRed:green:blue:alpha:)]) {
[pixel getRed:&red green:&green blue:&blue alpha:&alpha];
} else {
const CGFloat *components = CGColorGetComponents(pixel.CGColor);
red = components[0];
green = components[1];
blue = components[2];
alpha = components[3];
}
red = red * 255;
green = green * 255;
blue = blue * 255;
if(alpha > 0){
if(red < 50 && green < 50 && blue < 50){
[fixedRGBA addObject:pixel];
}
else{
[fixedRGBA addObject:armyColor];
}
}
else{
[fixedRGBA addObject:pixel];
}
}
return [self createImageWithRGB:fixedRGBA width:width height:height];
}
我遇到的问题是,当再次绘制图像时,因为alpha值为0而过去空白的所有像素都显示为白色。如何让这些像素仍然显示为清晰像素?
答案 0 :(得分:3)
创建图像时,应指定它包含Alpha通道。也就是说,而不是:
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
使用:
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaLast;
有关详细信息,请参阅the CGImage interface specification。
答案 1 :(得分:1)
我相信你的其他条款就是你要设置清除颜色的地方
if(alpha > 0){
rawData[4*i] = red * 255;
rawData[4*i+1] = green * 255;
rawData[4*i+2] = blue * 255;
rawData[4*i+3] = alpha * 255;
}
else{
rawData[4*i] = 255;
rawData[4*i+1] = 255;
rawData[4*i+2] = 255;
rawData[4*i+3] = 255;
}
您必须将最后一个分配更改为0
if(alpha > 0){
rawData[4*i] = red * 255;
rawData[4*i+1] = green * 255;
rawData[4*i+2] = blue * 255;
rawData[4*i+3] = alpha * 255;
}
else{
rawData[4*i] = 255;
rawData[4*i+1] = 255;
rawData[4*i+2] = 255;
rawData[4*i+3] = 0;
}