cocos2d中更改CCSprite的饱和度、色相、亮度等属性

3 篇文章 0 订阅

记录一下自己开发学习过程中遇到的问题吧。

本来CCSprite是没有色相、饱和度等属性的,但是CCSprite是通过CCTexture2D绘制的,而CCTexture2D可以通过UIImage创建,所以只要更改UIImage的属性就可以了。下面是大概的步骤:

1、给UIImage增加类别,实现方法:

- (UIImage*) copyImageWithHue:(int)hValue saturation:(int)sValue bright:(int)bValue;

2、创建自己的Sprite类,继承于CCSprite,实现方法:

- (id) initWithFile:(NSString *)filename withHue:(int)h withSaturation:(int)s withBright:(int)b;

3、在需要的地方导入头文件,创建Sprite。

4、具体的代码如下:

1>类别 .m文件

//交换
static inline void SwapRGB(int *a, int *b){
	*a+=*b;
	*b=*a-*b;
	*a-=*b;
}
//范围
static inline void CheckRGB(int *Value)
{
    if (*Value < 0) *Value = 0;
    else if (*Value > 255) *Value = 255;
}
//赋值
static inline void AssignRGB(int *R, int *G, int *B, int intR, int intG, int intB)
{
    *R = intR;
    *G = intG;
    *B = intB;
}
//设置明亮
static void SetBright(int *R, int *G, int *B, int bValue)
{
    int intR = *R;
    int intG = *G;
    int intB = *B;
    if (bValue > 0)
    {
        intR = intR + (255 - intR) * bValue / 255;
        intG = intG + (255 - intG) * bValue / 255;
        intB = intB + (255 - intB) * bValue / 255;
    }
    else if (bValue < 0)
    {
        intR = intR + intR * bValue / 255;
        intG = intG + intG * bValue / 255;
        intB = intB + intB * bValue / 255;
    }
    CheckRGB(&intR);
    CheckRGB(&intG);
    CheckRGB(&intB);
    AssignRGB(R, G, B, intR, intG, intB);
}
//设置色相和饱和度
static void SetHueAndSaturation(int *R, int *G, int *B, int hValue, int sValue)
{
    int intR = *R;
    int intG = *G;
    int intB = *B;
	
    if (intR < intG)
        SwapRGB(&intR, &intG);
    if (intR < intB)
        SwapRGB(&intR, &intB);
    if (intB > intG)
        SwapRGB(&intB, &intG);
	
    int delta = intR - intB;
    if (!delta) return;
	
    int entire = intR + intB;
    int H, S, L = entire >> 1;  //右移一位其实就是除以2(很巧妙)
    if (L < 128)
        S = delta * 255 / entire;
    else
        S = delta * 255 / (510 - entire);
    
    if (hValue)
    {
        if (intR == *R)
            H = (*G - *B) * 60 / delta;
        else if (intR == *G)
            H = (*B - *R) * 60 / delta + 120;
        else
            H = (*R - *G) * 60 / delta + 240;
        H += hValue;
        if (H < 0) H += 360;
        else if (H > 360) H -= 360;
        int index = H / 60;
        int extra = H % 60;
        if (index & 1) extra = 60 - extra;
        extra = (extra * 255 + 30) / 60;
        intG = extra - (extra - 128) * (255 - S) / 255;
        int Lum = L - 128;
        if (Lum > 0)
            intG += (((255 - intG) * Lum + 64) / 128);
        else if (Lum < 0)
            intG += (intG * Lum / 128);
        CheckRGB(&intG);
        switch (index)
        {
            case 1:
                SwapRGB(&intR, &intG);
                break;
            case 2:
                SwapRGB(&intR, &intB);
                SwapRGB(&intG, &intB);
                break;
            case 3:
                SwapRGB(&intR, &intB);
                break;
            case 4:
                SwapRGB(&intR, &intG);
                SwapRGB(&intG, &intB);
                break;
            case 5:
                SwapRGB(&intG, &intB);
                break;
        }
    }
    else
    {
        intR = *R;
        intG = *G;
        intB = *B;
    }
    if (sValue)
    {
        if (sValue > 0)
        {
            sValue = sValue + S >= 255? S: 255 - sValue;
            sValue = 65025 / sValue - 255;
        }
        intR += ((intR - L) * sValue / 255);
        intG += ((intG - L) * sValue / 255);
        intB += ((intB - L) * sValue / 255);
        CheckRGB(&intR);
        CheckRGB(&intG);
        CheckRGB(&intB);
    }
    AssignRGB(R, G, B, intR, intG, intB);
}

static CGContextRef RequestImagePixelData(CGImageRef inImage)
{
	CGContextRef context = NULL;
	
	size_t pixelsWide = CGImageGetWidth(inImage);
	size_t pixelsHigh = CGImageGetHeight(inImage);
	size_t bitmapBytesPerRow	= (pixelsWide * 4);
	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
	
	//size_t bitmapByteCount	= (bitmapBytesPerRow * pixelsHigh);
	//bitmapData = malloc( bitmapByteCount );
	void *bitmapData = calloc( pixelsWide*pixelsHigh,4);
	if (bitmapData == NULL)
	{
		fprintf (stderr, "Memory not allocated!");
		CGColorSpaceRelease( colorSpace );
		return NULL;
	}
	
	context = CGBitmapContextCreate (bitmapData, pixelsWide, pixelsHigh, 8, bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
	
	CGRect rect = {{0,0},{pixelsWide, pixelsHigh}};
	CGContextDrawImage(context, rect, inImage);
	
	CGColorSpaceRelease( colorSpace );
	return context;
}

- (UIImage*) copyImageWithHue:(int)hValue saturation:(int)sValue bright:(int)bValue{
	if (hValue==0&&sValue==0&&bValue==0) {
		UIImage *my_Image=nil;
		if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) {
			my_Image=[UIImage imageWithCGImage:[self CGImage] scale:self.scale orientation:self.imageOrientation];
		}else {
			my_Image = [UIImage imageWithCGImage:[self CGImage]];
		}
		return my_Image;
	}
	
	
	sValue = sValue * 255 / 100;
    bValue = bValue * 255 / 100;
	
	CGImageRef inImageRef = [self CGImage];
	CGContextRef cgctx = RequestImagePixelData(inImageRef);
	if (cgctx==NULL) {
		fprintf (stderr, "Create PixelData error!");
		return nil;
	}
	NSUInteger w = CGBitmapContextGetWidth(cgctx);
	NSUInteger h = CGBitmapContextGetHeight(cgctx);
	unsigned char *imgPixel = CGBitmapContextGetData(cgctx);
	
	int pixOff = 0;  //每一个像素结束
	
	for(NSUInteger y = 0;y< h;y++){
		for (NSUInteger x = 0; x<w; x++){
			//int alpha = (unsigned char)imgPixel[pixOff];
			int red = (unsigned char)imgPixel[pixOff];
			int green = (unsigned char)imgPixel[pixOff+1];
			int blue = (unsigned char)imgPixel[pixOff+2];
			
			if ((red|green|blue)!=0) {
				//根据条件的不同,对图片的处理顺序不一样
				if (sValue > 0 && bValue)
					SetBright(&red, &green, &blue, bValue);
				
				SetHueAndSaturation(&red, &green, &blue, hValue, sValue);
				
				if (bValue && sValue <= 0)
					SetBright(&red, &green, &blue, bValue);
			}
			
			imgPixel[pixOff] = red;
			imgPixel[pixOff+1] = green;
			imgPixel[pixOff+2] = blue;
			
			pixOff += 4;
		}
	}
	
	CGImageRef imageRef = CGBitmapContextCreateImage(cgctx);
	
	UIImage *my_Image=nil;
	if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) {
		my_Image=[UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];
	}else {
		my_Image = [UIImage imageWithCGImage:imageRef];
	}
	
	CFRelease(imageRef);
	CGContextRelease(cgctx);
	free(imgPixel);
	return my_Image;
}

2>自定义Sprite .m文件

- (id) initWithFile:(NSString *)filename withHue:(int)h withSaturation:(int)s withBright:(int)b
{
    if (self = [super init])
    {
        UIImage* image = [UIImage imageNamed:filename];
        UIImage* newimage = [image copyImageWithHue:h saturation:s bright:b];
        self = (YSGOrderCCSprite *)[self convertImageToSprite:newimage];
    }
    
    return self;
}

- (CCSprite *) convertImageToSprite:(UIImage *)image
{
    CGImageRef imageref = image.CGImage;
    
    CCTexture2D* texture = [[CCTexture2D alloc] initWithCGImage:imageref resolutionType:kCCResolutioniPhoneRetinaDisplay];
    CCSprite* sprite = [CCSprite spriteWithTexture:texture];
    [texture release];
    return sprite;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值