2011-08-24 155 views
5

我有一个“房间”图像。用另一种颜色替换图像中的特定颜色

现在,用户将点击任何特定的颜色假设图像中的蓝色。

而且用户还将选择替换颜色,如“黑色”颜色。

因此,图像内的所有“蓝色”颜色将被替换为“黑色”颜色。

任何人有想法如何在iPhone中实现这一点?

帮助表示赞赏。

+0

是的,完美的色彩替换是可能的,但它不会真正在真实世界的视频数据中工作。看到这个问题的更多信息和一个真正的解决方案:https://stackoverflow.com/questions/18452808/gpuimage-masking-transparency – MoDJ

回答

6
  1. 你必须通过每个像素的图像中进行迭代,并采取它的RGB值
  2. 检查它的RGB值相匹配的fromColor RGB值,如果是 像素的值更改为toColor RGB values.If不,见好就收 该像素,并转到下一个..

写了一个函数从memory..errors possible..correct自己

-(UIImage*)changeColor:(UIImage*)myImage fromColor:(UIColor*)fromColor toColor:(UIColor*)toColor{ 
    CGImageRef originalImage = [myImage CGImage]; 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef bitmapContext = 
CGBitmapContextCreate(NULL,CGImageGetWidth(originalImage),CGImageGetHeight(originalImage), 
8,CGImageGetWidth(originalImage)*4,colorSpace,kCGImageAlphaPremultipliedLast); 
    CGColorSpaceRelease(colorSpace); 
    CGContextDrawImage(bitmapContext, CGRectMake(0, 0, 
CGBitmapContextGetWidth(bitmapContext),CGBitmapContextGetHeight(bitmapContext)), 
originalImage); 
    UInt8 *data   = CGBitmapContextGetData(bitmapContext); 
    int numComponents = 4; 
    int bytesInContext = CGBitmapContextGetHeight(bitmapContext) *  
    CGBitmapContextGetBytesPerRow(bitmapContext); 
    double redIn, greenIn, blueIn,alphaIn; 
    CGFloat fromRed,fromGreen,fromBlue,fromAlpha; 
    CGFloat toRed,toGreen,toBlue,toAlpha; 

    //Get RGB values of fromColor 
    int fromCountComponents = CGColorGetNumberOfComponents([fromColor CGColor]); 
    if (fromCountComponents == 4) { 
    const CGFloat *_components = CGColorGetComponents([fromColor CGColor]); 
    fromRed = _components[0]; 
    fromGreen = _components[1]; 
    fromBlue = _components[2]; 
    fromAlpha = _components[3]; 
    } 


    //Get RGB values for toColor 
    int toCountComponents = CGColorGetNumberOfComponents([toColor CGColor]); 
    if (toCountComponents == 4) { 
     const CGFloat *_components = CGColorGetComponents([toColor CGColor]); 
     toRed = _components[0]; 
     toGreen = _components[1]; 
     toBlue = _components[2]; 
     toAlpha = _components[3]; 
    } 


    //Now iterate through each pixel in the image.. 
    for (int i = 0; i < bytesInContext; i += numComponents) { 
     //rgba value of current pixel.. 
     redIn = (double)data[i]/255.0; 
     greenIn = (double)data[i+1]/255.0; 
     blueIn = (double)data[i+2]/255.0; 
     alphaIn = (double)data[i+3]/255.0; 

     //now you got current pixel rgb values...check it curresponds with your fromColor 
     if(redIn == fromRed && greenIn == fromGreen && blueIn == fromBlue){ 
      //image color matches fromColor, then change current pixel color to toColor 
      data[i] = toRed; 
      data[i+1] = toGreen; 
      data[i+2] = toBlue; 
      data[i+3] = toAlpha;  
     } 
    } 
    CGImageRef outImage = CGBitmapContextCreateImage(bitmapContext); 
    myImage    = [UIImage imageWithCGImage:outImage]; 
    CGImageRelease(outImage); 
    return myImage; 
} 

我希望你不会每次都调用这个函数......它有点重要..如果我是你的处理器,我不会对你感到高兴.. :)

+0

Dint为我工作。在颜色 – Shailesh

+0

@Shailesh没有得到任何改变,这个代码是在很多年前写的,当时没有可用于iOS的本地图像过滤库。 iOS现在拥有核心图像框架,可能这就是你应该研究的内容。 – Krishnabhadra

+0

是的..我正在那样做。顺便说一句..这是我发布的问题。 http://stackoverflow.com/questions/27482508/virtual-wall-painting-like-app-ios 我将不胜感激,如果你能帮助 – Shailesh

0

你需要以某种方式访问​​原始像素数据(请参阅this answer或用户Krishnabhadra的代码)。搜索所有像素,例如蓝色 - >黑色替换,用黑色替换所有蓝色像素。看看将颜色转换为HSV,这将使颜色替换计算更容易。

0

我修改了一个小的Krishnabhadra的代码,因为我使用的是RGB颜色输入和输出如:

[的UIColor colorWithRed:191.0f/255.0f绿色:30.0f/255.0f蓝:45.0 f/255.0f alpha:1.0f]

适用于我。

-(UIImage*)changeColor:(UIImage*)myImage fromColor:(UIColor*)fromColor toColor:(UIColor*)toColor{ 
CGImageRef originalImage = [myImage CGImage]; 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef bitmapContext = 
CGBitmapContextCreate(NULL,CGImageGetWidth(originalImage),CGImageGetHeight(originalImage), 
         8,CGImageGetWidth(originalImage)*4,colorSpace,kCGImageAlphaPremultipliedLast); 
CGColorSpaceRelease(colorSpace); 
CGContextDrawImage(bitmapContext, CGRectMake(0, 0, 
              CGBitmapContextGetWidth(bitmapContext),CGBitmapContextGetHeight(bitmapContext)), 
        originalImage); 
UInt8 *data   = CGBitmapContextGetData(bitmapContext); 
int numComponents = 4; 
int bytesInContext = CGBitmapContextGetHeight(bitmapContext) * 
CGBitmapContextGetBytesPerRow(bitmapContext); 
double redIn, greenIn, blueIn,alphaIn; 
CGFloat fromRed,fromGreen,fromBlue,fromAlpha; 
CGFloat toRed,toGreen,toBlue,toAlpha; 

//Get RGB values of fromColor 
int fromCountComponents = CGColorGetNumberOfComponents([fromColor CGColor]); 
if (fromCountComponents == 4) { 
    const CGFloat *_components = CGColorGetComponents([fromColor CGColor]); 
    fromRed = _components[0]; 
    fromGreen = _components[1]; 
    fromBlue = _components[2]; 
    fromAlpha = _components[3]; 
} 


//Get RGB values for toColor 
int toCountComponents = CGColorGetNumberOfComponents([toColor CGColor]); 
if (toCountComponents == 4) { 
    const CGFloat *_components = CGColorGetComponents([toColor CGColor]); 
    toRed = _components[0]*255; 
    toGreen = _components[1]*255; 
    toBlue = _components[2]*255; 
    toAlpha = _components[3]*255; 
} 


//Now iterate through each pixel in the image.. 
for (int i = 0; i < bytesInContext; i += numComponents) { 
    //rgba value of current pixel.. 
    redIn = (double)data[i]; 
    greenIn = (double)data[i+1]; 
    blueIn = (double)data[i+2]; 
    alphaIn = (double)data[i+3]; 
    //now you got current pixel rgb values...check it curresponds with your fromColor 
    if(redIn == fromRed && greenIn == fromGreen && blueIn == fromBlue && alphaIn != 0){ 
     //image color matches fromColor, then change current pixel color to toColor 
     data[i] = toRed; 
     data[i+1] = toGreen; 
     data[i+2] = toBlue; 
     data[i+3] = toAlpha; 
    } 
} 
CGImageRef outImage = CGBitmapContextCreateImage(bitmapContext); 
myImage    = [UIImage imageWithCGImage:outImage]; 
CGImageRelease(outImage); 
return myImage;} 
0

我偶然发现了这个答案,寻找用另一种颜色代替颜色。 那么,因为我需要Swift代码,我有几次尝试,我找到了一个很好的解决方案。感谢@Rob的answer

extension UIImageView { 

    @discardableResult func replace(color: UIColor, withColor replacingColor: UIColor) -> Bool { 
     guard let inputCGImage = self.image?.cgImage else { 
      return false 
     } 
     let colorSpace  = CGColorSpaceCreateDeviceRGB() 
     let width   = inputCGImage.width 
     let height   = inputCGImage.height 
     let bytesPerPixel = 4 
     let bitsPerComponent = 8 
     let bytesPerRow  = bytesPerPixel * width 
     let bitmapInfo  = RGBA32.bitmapInfo 

     guard let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo) else { 
      print("unable to create context") 
      return false 
     } 
     context.draw(inputCGImage, in: CGRect(x: 0, y: 0, width: width, height: height)) 

     guard let buffer = context.data else { 
      return false 
     } 

     let pixelBuffer = buffer.bindMemory(to: RGBA32.self, capacity: width * height) 

     let inColor = RGBA32(color: color) 
     let outColor = RGBA32(color: replacingColor) 
     for row in 0 ..< Int(height) { 
      for column in 0 ..< Int(width) { 
       let offset = row * width + column 
       if pixelBuffer[offset] == inColor { 
        pixelBuffer[offset] = outColor 
       } 
      } 
     } 

     guard let outputCGImage = context.makeImage() else { 
      return false 
     } 
     self.image = UIImage(cgImage: outputCGImage, scale: self.image!.scale, orientation: self.image!.imageOrientation) 
     return true 
    } 

} 

哪里RGBA32结构很简单:

struct RGBA32: Equatable { 
    private var color: UInt32 

    var redComponent: UInt8 { 
     return UInt8((self.color >> 24) & 255) 
    } 

    var greenComponent: UInt8 { 
     return UInt8((self.color >> 16) & 255) 
    } 

    var blueComponent: UInt8 { 
     return UInt8((self.color >> 8) & 255) 
    } 

    var alphaComponent: UInt8 { 
     return UInt8((self.color >> 0) & 255) 
    } 

    init(red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8) { 
     self.color = (UInt32(red) << 24) | (UInt32(green) << 16) | (UInt32(blue) << 8) | (UInt32(alpha) << 0) 
    } 

    init(color: UIColor) { 
     let components = color.cgColor.components ?? [0.0, 0.0, 0.0, 1.0] 
     let colors = components.map { UInt8($0 * 255) } 
     self.init(red: colors[0], green: colors[1], blue: colors[2], alpha: colors[3]) 
    } 

    static let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Little.rawValue 

    static func ==(lhs: RGBA32, rhs: RGBA32) -> Bool { 
     return lhs.color == rhs.color 
    } 

} 

这样,无论在你的代码:

let imageView = UIImageView() 
let image = UIImage(color: .red) // (*) 
imageView.image = image 
imageView.replace(color: .red, withColor: .green) 

(*)的彩色图像创建解释here

相关问题