UIView对应坐标的颜色透明度

167 阅读1分钟

获取UIView对应坐标的颜色透明度方法

目前的原理都是通过CALayer绘制上下文,生成bitmap的颜色,转换出透明度来计算

期待更高性能的做法

方法1

- (UIColor *)colorfPoint: (CGPoint)point {
    unsigned char pixel[4] = {0};

    CGColorSpaceRe colorSpace = CGColorSpaceCreateDeviceGB ();

    CGContextRef context = CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast);

    CGContextTranslateCTM(context, -point.x, -point.y);

    [self.layer renderInContext:context];

    CGContextRelease (context);

    CGColorSpaceRelease(colorSpace);

    UIColor *color = [UIColor colorWithRed:pixel[0]/255.0 green:pixel[1]/255.0 blue:pixel[2]/255.0 alpha:pixel[3]/255.01;

    return color;
}

方法2

- (BOOL)isTransparent:(CGPoint)point {
    unsigned char pixel[4] = {0};

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGContextRef context = CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast);

    CGContextTranslateCTM(context, -point.x, -point.y );

    UIGraphicsPushContext(context);
    [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
    UIGraphicsPopContext();

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    
    return (pixel[0] / 255.0 == 0) && (pixel[1] / 255.0 == 0) && (pixel[2] / 255.0 == 0) && (pixel[3] / 255.0 == 0) ;
}

方法3

// 判断图像中指定位置是否透明
    func isPointTransparent(_ point: CGPoint, in image: UIImage) -> Bool {
        guard let cgImage = image.cgImage else {
            return false
        }
        
        let width = cgImage.width
        let height = cgImage.height
        
        let targetX = Int(point.x)
        let targetY = Int(point.y)
        
        // 检查目标点是否在图像范围内
        if targetX < 0 || targetX >= width || targetY < 0 || targetY >= height {
            return false
        }
        //获取图像的数据提供者
        guard let provider = cgImage.dataProvider else {
            return false
        }

        // 获取图像的数据并将其转换为字节数组
        guard let pixelData = provider.data, let data = CFDataGetBytePtr(pixelData) else {
            return false
        }
        //获取图像的alpha信息
        let alphaInfo = cgImage.alphaInfo
      
        let bytesPerPixel = cgImage.bitsPerPixel / 8
        let pixelOffset = (targetY * cgImage.bytesPerRow) + (targetX * bytesPerPixel)
        if alphaInfo == .none {
            // 对于没有透明度通道的图像,直接判断颜色通道是否为0
            return data[pixelOffset] == 0 && data[pixelOffset + 1] == 0 && data[pixelOffset + 2] == 0
        } else {
            // 对于有透明度通道的图像,判断透明度是否为0
            return data[pixelOffset + bytesPerPixel - 1] == 0
        }
    }