2011-08-24 47 views
5

Tôi có một hình ảnh "phòng".Thay thế một màu cụ thể bên trong hình ảnh bằng một màu khác

Bây giờ, người dùng sẽ nhấp vào bất kỳ màu cụ thể nào giả sử màu xanh lam trong hình ảnh.

Và người dùng cũng sẽ chọn màu thay thế như màu "đen".

Vì vậy, tất cả màu "xanh" bên trong hình ảnh sẽ được thay thế bằng màu "đen".

Bất kỳ ai có ý tưởng về cách đạt được điều này trong iPhone?

Trợ giúp được đánh giá cao.

+0

Có, thay thế màu hoàn hảo là có thể, nhưng nó sẽ không thực sự hoạt động trong dữ liệu video thế giới thực. Xem câu hỏi này để biết thêm thông tin và giải pháp thực tế: https://stackoverflow.com/questions/18452808/gpuimage-masking-transparency – MoDJ

Trả lời

6
  1. Bạn phải lặp qua mỗi điểm ảnh trong hình ảnh và chịu rgb nó giá trị
  2. Kiểm tra giá trị rgb của nó phù hợp với các giá trị rgb fromColor của bạn, nếu có thay đổi giá trị pixel để toColor rgb bạn values.If không , chỉ để lại pixel và đi đến tiếp theo ..

Đã viết một hàm từ memory..errors possible..correct mình

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

Tôi hy vọng bạn không gọi chức năng này mỗi lần ... Đó là một bộ xử lý bit nặng .. Và nếu tôi là bộ xử lý của bạn, tôi sẽ không hài lòng với bạn .. :)

+0

Dint làm việc cho tôi.đã không nhận được bất kỳ thay đổi nào về màu sắc – Shailesh

+0

@Shailesh, mã này được viết cách đây nhiều năm khi không có thư viện lọc hình ảnh gốc nào có sẵn cho iOS. iOS hiện có khung hình ảnh cốt lõi và có lẽ đó là những gì bạn nên xem xét. – Krishnabhadra

+0

Vâng .. Tôi đang làm điều đó. Btw .. đây là câu hỏi tôi đã đăng. http://stackoverflow.com/questions/27482508/virtual-wall-painting-like-app-ios Tôi sẽ đánh giá cao nếu bạn có thể giúp – Shailesh

0

Bạn sẽ cần truy cập dữ liệu pixel thô bằng cách nào đó (xem this answer hoặc mã của người dùng Krishnabhadra). Tìm kiếm thông qua tất cả các pixel và ví dụ: thay thế màu xanh - đen, thay thế tất cả các pixel màu xanh lam bằng màu đen. Nhìn vào chuyển đổi màu sắc để HSV mà sẽ làm cho tính toán thay thế màu sắc dễ dàng hơn.

0

tôi sửa đổi một chút mã Krishnabhadra của của, kể từ khi tôi đang sử dụng RGB cho đầu vào màu sắc cũng như đầu ra ví dụ:

[UIColor colorWithRed: 191.0f/255.0f xanh: 30.0f/255.0f xanh: 45,0 f/255.0f alpha: 1.0f]

Làm việc cho tôi.

-(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

Tôi vấp trong câu trả lời này để tìm cách thay thế màu bằng màu khác. Vâng, vì tôi cần cho mã Swift, tôi đã có một số thử và tôi tìm thấy một giải pháp tốt đẹp. Cảm ơn @Rob vì số 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 
    } 

} 

đâu RGBA32 struct chỉ đơn giản là:

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 
    } 

} 

Bằng cách này, bất cứ nơi nào trong mã của bạn:

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

(*) tạo ra hình ảnh với màu sắc được giải thích here.

Các vấn đề liên quan