2013-04-26 12 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

このコードは、顔や髪だけでなく、すべての画像を変更しますか? –

+0

@SAMIR RATHODさんはイメージの顔の色の変化と同じ質問で私を助けることができますか? http://stackoverflow.com/questions/37113740/change-face-color-from-main-color-in-xcode?noredirect=1#comment61769372_37113740 –

答えて

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に赤のチャンネルを割り当てている:ところで

は、私はあなたがこのことを知っていると推定します。私はそれがあなたが望むものだとは思わない。

また、needToModified画像はfirstImageV.imageと同じ画像であることを前提としていますが、現時点ではコードに反映されていません。

この方法は、特定された色の範囲が画像の肉部分にのみ存在する場合にのみ有効です。

長い答えは

+0

AND演算子を適用すると、画像からいくつかのピクセルが残され、すべての私は肌の色だけを変えたい。 – madhyamika

+1

"このアプローチは、特定された色の範囲が画像の肉の領域内にのみ存在する場合にのみ有効です。" ...これはあなたの関心領域を選択するための非常に粗雑なアプローチです。 Photoshopのマジックワンドツールのようなものは、画像の隣接する類似の領域と対話的なユーザー入力/ UIを選択する必要があります。私は[openCV](http://openCV.org)を調査することをお勧めします... – foundry

0

は、画像をマスキングしてみ...色の範囲のより洗練された選択、画像領域、CIFilterの使用またはOpenCVの枠組みを選択する別の方法で見ることができる...それがされます

- (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; 
} 
1

は、ブラッド・ラーソンによるGPUImageフレームワークを使用してみてください:

0マスク

コードで定義された特定の色の範囲を変更するには、ヘルプ

https://github.com/BradLarson/GPUImage

これは、画像を操作するための非常に強力なフレームワークです。

GPUImage create a custom Filter that change selected colors

はそれが役に立てば幸い:

は、この質問を読んで!

0

CFDataGetBytePtr CFDataGetBytePtr CFDataオブジェクトのバイトへの読み取り専用ポインタを返します。CFDataGetBytesを探していませんか?CFDataオブジェクトのバイト内容を外部バッファにコピーしますか?その場合、あなたのバッファにwidth * height * 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

顔と髪をオブジェクトにします。オブジェクトには色があり、色を変更するグローバルな方法があります。あなたのメインで、両方のオブジェクト(髪、顔)を作成し、正確に色付けするものを指定します。これは正しいアプローチです。それが役に立てば幸い!

関連する問題