【问题标题】:Area covered with the same pixel colour and change it用相同像素颜色覆盖的区域并更改它
【发布时间】:2017-06-02 10:27:50
【问题描述】:

如何擦除被相同颜色覆盖的特定像素和像素区域的颜色。我可以使用下面的快速代码获得特定像素颜色,但我无法获得具有相同颜色像素的周围区域并且无法擦掉它。

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,则它必须获取颜色并擦除具有相同颜色的像素和周围像素,并且所有这些都必须擦除。请帮我解决这个问题。

【问题讨论】:

    标签: ios objective-c colors uiimage pixels


    【解决方案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 坐标更改颜色,这与洪水填充算法相同,但我想获取特定坐标处的颜色像素以及该坐标中相同颜色像素覆盖的区域然后删除它。
    • 即使他点击了绿色像素被选中的图像,请查看下面的视频,所以我会以同样的方式照顾它。当我单击图像触摸位置坐标像素颜色时,必须选择相同的相关像素。 youtube.com/watch?v=DG38mAWKE1c
    • 谁能帮我解决这个问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多