【问题标题】:ios, can't get correct pixel color of CGImageRefios,无法获得正确的 CGImageRef 像素颜色
【发布时间】:2014-03-04 14:14:56
【问题描述】:

我做了一个上下文,然后是一个渐变。之后,我将根据上下文进行绘制。然后我从上下文中收到一个渐变图像,它是正确的,我可以在调试器中看到它。但是,当我尝试获取特定值的像素颜色时,它是不正确的。我感谢任何帮助,谢谢。这是代码。

- (UIColor*) getColorForPoint: (CGPoint) point imageWidth: (NSInteger) imageHeight
{
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    // create a gradient

    CGPoint startPoint = CGPointMake(0, 0);
    CGPoint endPoint = CGPointMake(imageHeight, 0);

    // create a bitmap context to draw the gradient to, 1 pixel high.
    CGContextRef context = CGBitmapContextCreate(NULL, imageHeight, 1, 8, 0, colorSpace,     kCGImageAlphaPremultipliedLast);

    // draw the gradient into it
    CGContextAddRect(context, CGRectMake(0, 0, imageHeight, 1));
    CGContextClip(context);
    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);

    // Get our RGB bytes into a buffer with a couple of intermediate steps...
    //      CGImageRef -> CFDataRef -> byte array
    CGImageRef cgImage = CGBitmapContextCreateImage(context);
    CGDataProviderRef provider = CGImageGetDataProvider(cgImage);
    CFDataRef pixelData = CGDataProviderCopyData(provider);

    // cleanup:
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(cgImage);
    CGContextRelease(context);

    const UInt8* data = CFDataGetBytePtr(pixelData);

    // we got all the data we need.
    // bytes in the data buffer are a succession of R G B A bytes

    CGFloat y = 100 * point.y / imageHeight;
    int pixelIndex = (int)y * 4; // 4 bytes per color
    UIColor *color = [UIColor colorWithRed:data[pixelIndex + 0]/255.0f
                                 green:data[pixelIndex + 1]/255.0f
                                  blue:data[pixelIndex + 2]/255.0f
                                 alpha:data[pixelIndex + 3]/255.0f];

    // done fetching color data, finally release the buffer
    CGDataProviderRelease(provider);

    return color;
}

【问题讨论】:

    标签: ios gradient uicolor cgimageref raw-data


    【解决方案1】:

    我测试了您的代码,问题似乎是在计算 pixelIndex 之前对 point.y 进行了乘法运算:

    CGFloat y = 100 * point.y / imageHeight;
    int pixelIndex = (int)y * 4; // 4 bytes per color
    

    我从您的代码中删除了它,它可以工作。还将point 更改为int 以匹配imageWidth 参数,并将其限制为始终为0 <= point < imageWidth

    - (UIColor*) getColorForPoint: (NSInteger) point imageWidth: (NSInteger) imageWidth
    {
        point = MIN(imageWidth - 1, MAX(0, point));
    
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    
        // create a gradient
    
        CGPoint startPoint = CGPointMake(0, 0);
        CGPoint endPoint = CGPointMake(imageWidth, 0);
    
        // create a bitmap context to draw the gradient to, 1 pixel high.
        CGContextRef context = CGBitmapContextCreate(NULL, imageWidth, 1, 8, 0, colorSpace,     kCGImageAlphaPremultipliedLast);
    
        // draw the gradient into it
        CGContextAddRect(context, CGRectMake(0, 0, imageWidth, 1));
        CGContextClip(context);
        CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
    
        // Get our RGB bytes into a buffer with a couple of intermediate steps...
        //      CGImageRef -> CFDataRef -> byte array
        CGImageRef cgImage = CGBitmapContextCreateImage(context);
        CGDataProviderRef provider = CGImageGetDataProvider(cgImage);
        CFDataRef pixelData = CGDataProviderCopyData(provider);
    
        // cleanup:
        CGColorSpaceRelease(colorSpace);
        CGImageRelease(cgImage);
        CGContextRelease(context);
    
        const UInt8* data = CFDataGetBytePtr(pixelData);
    
        // we got all the data we need.
        // bytes in the data buffer are a succession of R G B A bytes
    
        int pixelIndex = (int)point * 4; // 4 bytes per color
        UIColor *color = [UIColor colorWithRed:data[pixelIndex + 0]/255.0f
                                         green:data[pixelIndex + 1]/255.0f
                                          blue:data[pixelIndex + 2]/255.0f
                                         alpha:data[pixelIndex + 3]/255.0f];
    
        // done fetching color data, finally release the buffer
        CGDataProviderRelease(provider);
    
        return color;
    }
    

    【讨论】:

    • 太好了,很高兴我能帮上忙。你会认为我的回答是正确的吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-04
    相关资源
    最近更新 更多