相同像素颜色区域的覆盖和更改

8

如何擦除特定像素的颜色以及覆盖相同颜色的像素区域。我可以使用以下Swift代码获取特定像素颜色,但我无法获取周围具有相同颜色像素的区域,也无法擦除它。

import UIKit

class ColorOfImage: UIImageView {
    
    var lastColor:UIColor? = nil


    
    /*
     // Only override draw() if you perform custom drawing.
     // An empty implementation adversely affects performance during animation.
     override func draw(_ rect: CGRect) {
     // Drawing code
     }
     */
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        if self.isHidden == true {
            
            self.next?.touchesEnded(touches, with: event)
            return
        }
        
        let touch: UITouch = touches.first!
        
        var point:CGPoint = touch.location(in: self)
        self.lastColor = self.getPixelColorAtLocation(point:point)  
    }
    
    
    public func createARGBBitmapContext(inImage: CGImage) -> CGContext {

        var bitmapByteCount = 0
        var bitmapBytesPerRow = 0
        
        //Get image width, height
        let pixelsWide = inImage.width
        let pixelsHigh = inImage.height
        
        // Declare the number of bytes per row. Each pixel in the bitmap in this
        // example is represented by 4 bytes; 8 bits each of red, green, blue, and
        // alpha.
        bitmapBytesPerRow = Int(pixelsWide) * 4
        bitmapByteCount = bitmapBytesPerRow * Int(pixelsHigh)
        
        // Use the generic RGB color space.
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        
        
        
        // Allocate memory for image data. This is the destination in memory
        // where any drawing to the bitmap context will be rendered.
        let bitmapData = malloc(bitmapByteCount)
        
        // Create the bitmap context. We want pre-multiplied ARGB, 8-bits
        // per component. Regardless of what the source image format is
        // (CMYK, Grayscale, and so on) it will be converted over to the format
        // specified here by CGBitmapContextCreate.
        let context = CGContext(data: bitmapData, width: pixelsWide, height: pixelsHigh, bitsPerComponent: 8, bytesPerRow: bitmapBytesPerRow, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue)
        
        // Make sure and release colorspace before returning
        return context!
    }
    
    
    
    
    public func getPixelColorAtLocation( point:CGPoint) -> UIColor {
        // Create off screen bitmap context to draw the image into. Format ARGB is 4 bytes for each pixel: Alpa, Red, Green, Blue
        var point = point
        
        var context:CGContext? = nil
        
        context = self.createARGBBitmapContext(inImage: (self.image?.cgImage)!)
        
        
        if context == nil {
            return UIColor.white
        }
        
        var pixelsWide = (self.image?.cgImage)!.width
        var pixelsHigh = (self.image?.cgImage)!.height
        var rect = CGRect(x:0, y:0, width:Int(pixelsWide), height:Int(pixelsHigh))
        
        var xScale:CGFloat = CGFloat(pixelsWide)/self.frame.size.width
        var yScale:CGFloat = CGFloat(pixelsHigh)/self.frame.size.height
        
        
        point.x = point.x * xScale
        point.y = point.y * yScale
        
        
        
        var x:CGFloat = 1.0
        
        
        
        if (self.image?.responds(to: #selector(getter:  self.image?.scale)))! {
            x =  ( self.image!.scale)
            
        }
        
        
        
        //Clear the context
        context?.clear(rect)
        
        // Draw the image to the bitmap context. Once we draw, the memory
        // allocated for the context for rendering will then contain the
        // raw image data in the specified color space.
        
        context?.draw((self.image?.cgImage)!, in: rect)
        
        // Now we can get a pointer to the image data associated with the bitmap
        // context.
        
        
        let data = context?.data
        //    let dataType = UnsafePointer<UInt8>(data)
        
        var color:UIColor? = nil
        if data != nil {
            let dataType = data?.assumingMemoryBound(to: UInt8.self)
            
            
            let offset = 4*((Int(pixelsWide) * Int(point.y)) + Int(point.x))
            let alpha = dataType?[offset]
            let red = dataType?[offset+1]
            let green = dataType?[offset+2]
            let blue = dataType?[offset+3]
            color = UIColor(red: CGFloat(red!)/255.0, green: CGFloat(green!)/255.0, blue: CGFloat(blue!)/255.0, alpha: CGFloat(alpha!)/255.0)
        }
        else
        {
            
            
        }
        
        
        
        // Free image data memory for the context
        free(data)
        return color!;
    } 
}

例如,如果我在UIImage上触摸特定坐标,则必须获取颜色并擦除具有相同颜色的像素及其周围的所有像素。请问是否有人能够帮助我解决这个问题。
1个回答

1
一个月前,我曾为一个应用程序工作过,你可以在其中获得一张图片,并且必须交换颜色……我不知道这对你是否有用。我为此创建了UIImage的类别。
无论如何,以下是Objective-C代码:
#import <UIKit/UIKit.h>

@interface UIImage (YPKInterface)
+ (UIImage *)swapImage:(UIImage *)image color:(UIColor *)originalColor withColor:(UIColor *)swappedColor andThreshold:(float)threshold;
@end

#import "UIImage+YPKInterface.h"

@implementation UIImage (YPKInterface)

+ (UIImage *)swapImage:(UIImage *)image color:(UIColor *)originalColor     withColor:(UIColor *)swappedColor andThreshold:(float)threshold {

int count = image.size.width*image.size.height;

// Convert image in raw data
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

CGColorSpaceRelease(colorSpace);

CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);

// Scan all the pixels
NSUInteger byteIndex = 0;
for (int i = 0 ; i < count ; ++i)
{
    CGFloat alpha = ((CGFloat) rawData[byteIndex + 3] ) / 255.0f;
            CGFloat red   = ((CGFloat) rawData[byteIndex]     ) / alpha;
            CGFloat green = ((CGFloat) rawData[byteIndex + 1] ) / alpha;
            CGFloat blue  = ((CGFloat) rawData[byteIndex + 2] ) / alpha;

    // Change the color

    // RGBA of the colors
    float origR = CGColorGetComponents(originalColor.CGColor)[0] * 255;
    float origG = CGColorGetComponents(originalColor.CGColor)[1] * 255;
    float origB = CGColorGetComponents(originalColor.CGColor)[2] * 255;
    //float origA = CGColorGetComponents(originalColor.CGColor)[3];

    float swapR = CGColorGetComponents(swappedColor.CGColor)[0] * 255;
    float swapG = CGColorGetComponents(swappedColor.CGColor)[1] * 255;
    float swapB = CGColorGetComponents(swappedColor.CGColor)[2] * 255;
    //float swapA = CGColorGetComponents(swappedColor.CGColor)[3];

    if (red >= origR - threshold && red <= origR + threshold &&
        green >= origG - threshold && green <= origG + threshold &&
        blue >= origB - threshold && blue <= origB + threshold) {
        rawData[byteIndex + 3] = alpha * 255;
        rawData[byteIndex    ] = swapR * alpha;
        rawData[byteIndex + 1] = swapG * alpha;
        rawData[byteIndex + 2] = swapB * alpha;
    }

    byteIndex += bytesPerPixel;
}

CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, rawData, width*height*4, NULL);

CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();

CGBitmapInfo bitmapInfo =
kCGBitmapByteOrderDefault | kCGImageAlphaLast;

CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef imageRef2 = CGImageCreate(width, height, 8, 32, 4*width,colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

UIImage *newImage = [UIImage imageWithCGImage:imageRef2];

return newImage;
}

@end

这将从0,0坐标开始更改颜色,这与泛洪算法相同,但我想获取特定坐标处的彩色像素以及由该坐标覆盖的相同颜色像素区域,然后擦除它。 - Uttam
请查看下面的视频,即使他点击图像,绿色像素也会被选中,因此我正在寻找同样的方法。当我点击图像时,触摸位置坐标像素颜色和相关像素都必须被选中。 https://www.youtube.com/watch?v=DG38mAWKE1c - Uttam
有人可以帮我吗? - Uttam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接