2013-04-26 33 views
14

我的代码: 如何管理不同色调的RGB值以及如何应用? 这段代码会随着头发改变脸部的颜色,但我想要 1.只有脸部才会有颜色,不包括头发。如何更改ios中源图像的脸部肤色?

-(void)changeSkinColorValue:(float)value WithImage:(UIImage*)needToModified 
    { 

     CGContextRef ctx; 

     CGImageRef imageRef = needToModified.CGImage; 
     NSUInteger width = CGImageGetWidth(imageRef); 
     NSUInteger height = CGImageGetHeight(imageRef); 
     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
     //unsigned char *rawData = malloc(firstImageV.image.size.height * firstImageV.image.size.width * 10); 

     CFMutableDataRef m_DataRef = CFDataCreateMutableCopy(0, 0,CGDataProviderCopyData(CGImageGetDataProvider(firstImageV.image.CGImage))); 
     UInt8 *rawData = (UInt8 *) CFDataGetMutableBytePtr(m_DataRef); 
     int length = CFDataGetLength(m_DataRef); 
     NSUInteger bytesPerPixel = 4; 
     NSUInteger bytesPerRow = bytesPerPixel * firstImageV.image.size.width; 
     NSUInteger bitsPerComponent = 8; 

       CGContextRef context1 = CGBitmapContextCreate(rawData, firstImageV.image.size.width, firstImageV.image.size.height, bitsPerComponent, bytesPerRow, colorSpace,      kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
     CGColorSpaceRelease(colorSpace); 

     CGContextDrawImage(context1, CGRectMake(0, 0, firstImageV.image.size.width, firstImageV.image.size.height), imageRef); 

     NSLog(@"%d::%d",width,height); 


     // for(int ii = 0 ; ii < 250 ; ii+=4) 
     //{ 

      for(int ii = 0 ; ii < length ; ii+=4) 
      { 
      //NSLog(@"Raw data %s",rawData); 

      int R = rawData[ii]; 
      int G = rawData[ii+1]; 
      int B = rawData[ii+2]; 

      //  NSLog(@"%d %d %d", R, G, B); 
      //if(((R>60)&&(R<237)) || ((G>10)&&(G<120))||((B>4) && (B<120))) 
       //  if(((R>100)&&(R<186)) || ((G>56)&&(G<130))||((B>30) && (B<120))) 
       //  if(((R>188)&&(R<228)) || ((G>123)&&(G<163))||((B>85) && (B<125))) 
         // if(((R>95)&&(R<260)) || ((G>40)&&(G<210))||((B>20) && (B<170))) 

         //new code...... 

       if(((R>0)&&(R<260)) || ((G>0)&&(G<210))||((B>0) && (B<170))) 

        { 
         rawData[ii+1]=R;//13; 
         rawData[ii+2]=G;//43; 
         rawData[ii+3]=value;//63 
        } 
       } 


     ctx = CGBitmapContextCreate(rawData, 
          CGImageGetWidth(imageRef), 
          CGImageGetHeight(imageRef), 
          8, 
          CGImageGetBytesPerRow(imageRef), 
          CGImageGetColorSpace(imageRef), 
          kCGImageAlphaPremultipliedLast); 

     imageRef = CGBitmapContextCreateImage(ctx); 
     UIImage* rawImage = [UIImage imageWithCGImage:imageRef]; 
     //UIImageView *ty=[[UIImageView alloc]initWithFrame:CGRectMake(100, 200, 400, 400)]; 
     //ty.image=rawImage; 
     //[self.view addSubview:ty]; 
     [secondImageV setImage:rawImage]; 
     CGContextRelease(context1); 
     CGContextRelease(ctx); 
     free(rawData); 
    } 
+0

此代码不仅改变脸部和头发,而且改变所有图像,不是吗? – 2013-04-26 13:11:41

+0

@SAMIR RATHOD你能帮我解决图像颜色变化的问题吗? http://stackoverflow.com/questions/37113740/change-face-color-from-main-color-in-xcode?noredirect=1#comment61769372_37113740 – 2016-05-09 11:30:55

回答

0

简单的回答是改变你的手术室:

  if(((R>0)&&(R<260)) || ((G>0)&&(G<210)) || ((B>0) && (B<170))) 

到与运算:

  if(((R>0)&&(R<260)) && ((G>0)&&(G<210)) && ((B>0) && (B<170))) 

然后调整RGB范围近似肤色的范围内的图像(试在你的UI中有一些滑块)。

顺便说一句,我想你知道这个:

 rawData[ii+1]=R;//13; 
     rawData[ii+2]=G;//43; 
     rawData[ii+3]=value;//63 

被分配红色通道绿色通道,绿色通道,蓝色通道,并value Alpha通道。我不指望这是你想要的。

此外,您的needToModified图像可能与firstImageV.image的图像相同,因此它不会反映在您的代码中。

此方法仅适用于您的识别颜色范围完全且仅存在于图像的肉质区域中的情况。

一个答案可以看看颜色范围,选择图像区域,使用CIFilter或OpenCV的框架的替代方法的更复杂的选择...

+0

应用AND运算符后,它会留下一些像素和颜色的所有image.I只想改变肤色。 – madhyamika 2013-04-29 06:41:59

+1

“这种方法只有在您确定的颜色范围完全且仅存在于图像的肉质区域时才有效。”...这是选择您感兴趣的区域的非常粗糙的方法。你真的需要类似Photoshop的魔棒工具来选择图像的相邻区域和一些交互式用户输入/ UI。我建议你调查[openCV](http://openCV.org)... – foundry 2013-04-29 13:58:00

0

尝试掩蔽图像...这将有助于改变的面膜

代码中定义的颜色特定范围:

- (UIImage *)doctorTheImage:(UIImage *)originalImage 
{ 

    const float brownsMask[6] = {85, 255, 85, 255, 85, 255}; 


    UIImageView *imageView = [[UIImageView alloc] initWithImage:originalImage]; 

    UIGraphicsBeginImageContext(originalImage.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    CGContextSetRGBFillColor (context, 1.0,1.0, 1.0, 1); 


    CGContextFillRect(context, CGRectMake(0, 0, imageView.image.size.width, imageView.image.size.height)); 

    CGImageRef brownRef = CGImageCreateWithMaskingColors(imageView.image.CGImage, brownsMask); 

    CGRect imageRect = CGRectMake(0, 0, imageView.image.size.width, imageView.image.size.height); 

    CGContextTranslateCTM(context, 0, imageView.image.size.height); 
    CGContextScaleCTM(context, 1.0, -1.0); 
    //CGImageRef whiteRef = CGImageCreateWithMaskingColors(brownRef, whiteMask); 
    CGContextDrawImage (context, imageRect, brownRef); 

    //[originalImage drawInRect:CGRectMake(0, 0, imageView.image.size.width, imageView.image.size.height)]; 

    CGImageRelease(brownRef); 
    // CGImageRelease(whiteRef); 

    UIImage *doctoredImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return doctoredImage; 
} 
0

CFDataGetBytePtr根据文档,它返回一个指向CFData对象字节的只读指针,你确定你没有在寻找将CFData对象的字节内容复制到外部缓冲区的CFDataGetBytes。在这种情况下,您必须分配缓冲区来包含宽度*高度* bpp。一旦你有这个副本,你可以操纵它,无论如何你想创建新的图片。

像素选择根据你的问题,我似乎明白,你想改变肤色从白色到黑色。您当前的代码会遍历每个像素以更改其颜色。您应该评估像素颜色与您要查找的内容之间的“距离”,以及它是否低于某个阈值处理它。在HSV中执行操作可能比通过处理RGB颜色要容易得多

0

1)获取要应用算法的面部CGPath。 2)获取CGimage的宽度。

int width = CGImageGetWidth(image); 

3)获取当前处理像素的像素CGPoint。在应用您的算法之前检查条件。然后应用你的情况。而已。这是代码的示例部分。

CGFloat pointY = (int)(i/4)/(int)width; 
CGFloat pointX = (int)(i/4)%(int)width; 
CGPoint point = CGPointMake(pointX, pointY); 

if (CGPathContainsPoint(yourFacePath, NULL, point, NO)) 
{ 
    if(((R>0)&&(R<260)) || ((G>0)&&(G<210))||((B>0) && (B<170))) 
    { 
     rawData[ii+1]=R;//13; 
     rawData[ii+2]=G;//43; 
     rawData[ii+3]=value;//63 
    } 
} 
0

使脸和头发成为物体。对象具有颜色并且具有改变其颜色的全局方法。然后在你的主体中,制作两个物体(头发,脸部)并指定你想要的颜色。这是正确的方法。希望能帮助到你!