查询时为什么HSB值与绘图时不同?

时间:2013-12-30 23:31:16

标签: ios rgb uicolor hsb

首先,我创建了这个实用程序以调试我的情况:

+(NSString *)hsbaFromColor:(UIColor *)c
{
   CGFloat hue, saturation, brightness, alpha;
   NSString *returnValue;
   if ([c getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha]) {
      returnValue = [NSString stringWithFormat:@"H:%f S:%f B:%f A:%f",hue,saturation,brightness,alpha];
   }
   return returnValue;
}

此实用程序用于确认在读取刚绘制的值时,我没有收到预期的数据集。我希望得到的价值与刚刚绘制的相匹配。这是绘图代码:

CGContextSetLineCap(self.context, kCGLineCapRound);
CGContextSetStrokeColorWithColor(self.context, ant.color.CGColor);
CGContextSetLineWidth(self.context, ant.size.width*1.0);
CGContextMoveToPoint(self.context, ant.previousLocation.x, ant.previousLocation.y);
CGContextAddLineToPoint(self.context, ant.location.x, ant.location.y);
CGContextStrokePath(self.context);
NSLog(@"Draw color: %@",[ColorTools hsbaFromColor:ant.color]);
UIColor *colorJustDrawn = [self getColorFromContextAtPosition:ant.location];
NSLog(@"Read color: %@",[ColorTools hsbaFromColor:colorJustDrawn]);

在我的测试用例中,ant.size.width是5.这应该产生一条足够宽的线,当我查询颜色时,我应该得到相同的颜色。以下是查询颜色的方法:

-(UIColor *)getColorFromContextAtPosition:(CGPoint)p
{
   if (p.x < self.minX) {
      self.minX = p.x;
   }
   if (p.x > self.maxX) {
      self.maxX = p.x;
   }
   if (p.y < self.minY) {
      self.minY = p.y;
   }
   if (p.y > self.maxY) {
      self.maxY = p.y;
   }
   CGFloat screenScale = [[UIScreen mainScreen] scale];
   CGSize contextSize;
   contextSize.width = CGBitmapContextGetWidth(self.context);
   contextSize.height = CGBitmapContextGetHeight(self.context);
   unsigned char* data = CGBitmapContextGetData (self.context);
   UIColor *color = [UIColor whiteColor];
   if (data != NULL) {
        //offset locates the pixel in the data from x,y.
        //4 for 4 bytes of data per pixel, w is width of one row of data.
        int offset = 4*((contextSize.width*floorf(p.y*screenScale))+floorf(p.x*screenScale));
        int alpha =  data[offset+3];
        int red = data[offset+0];
        int green = data[offset+1];
        int blue = data[offset+2];
        color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:(blue/255.0f) alpha:(alpha/255.0f)];
   }
   return color;
}

我意识到这种方法是从不同的模式RGB中创建一种颜色,而不是所写的HSB,但由于我对两者使用相同的上下文,我认为这无关紧要。也许我需要设置一些其他设置?

以下是创建上下文的方法:

-(void)blankOutImageView{
   CGRect frame = self.mainImageView.bounds;
   UIGraphicsBeginImageContextWithOptions(frame.size, YES, 0.0);
   CGContextRef context = UIGraphicsGetCurrentContext();
   CGContextSetLineWidth(context, 1.0);
   CGContextSetFillColorWithColor(context, [UIColor grayColor].CGColor);
   CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor);
   CGContextMoveToPoint(context, 0.0, 0.0);
   CGContextAddRect(context, frame);
   CGContextFillRect(context, frame);
   CGContextStrokePath(context);
   CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
   CGContextStrokePath(context);

   UIImage *blank = UIGraphicsGetImageFromCurrentImageContext();
   self.context = context;
   self.mainImageView.image = blank;
}

以下是一些数据的示例。该应用程序选择随机颜色,通过在每次需要新颜色时添加黄金比例来交替色调,然后归一化为0..1。在我刚刚做的运行中,创建的颜色是:

H:0.537255 S:0.598039 B:1.000000 A:1.000000

使用以下代码创建:

self.lightColor = [UIColor colorWithHue:hue saturation:saturation brightness:1.0 alpha:1.0];

色调和饱和度的值是在蚂蚁的初始化时创建的,但在整个对象的生命周期内保持不变。在任何情况下,这里都是使用在屏幕上显示浅蓝蓝色的颜色从绘图和查询输出:

Draw color: H:0.537255 S:0.598039 B:0.995069 A:1.000000
Draw color: R:0.399979 G:0.862049 B:0.995069 A:1.000000

Read color: H:0.129386 S:0.598425 B:0.996078 A:1.000000
Read color: R:0.996078 G:0.862745 B:0.400000 A:1.000000

嗯。现在我看一下,似乎可能存在一个endian问题。看起来红色和蓝色都是落后的。

1 个答案:

答案 0 :(得分:0)

更改此方法可解决此问题。

-(UIColor *)getColorFromContextAtPosition:(CGPoint)p
{
   if (p.x < self.minX) {
      self.minX = p.x;
   }
   if (p.x > self.maxX) {
      self.maxX = p.x;
   }
   if (p.y < self.minY) {
      self.minY = p.y;
   }
   if (p.y > self.maxY) {
      self.maxY = p.y;
   }
   CGFloat screenScale = [[UIScreen mainScreen] scale];
   CGSize contextSize;
   contextSize.width = CGBitmapContextGetWidth(self.context);
   contextSize.height = CGBitmapContextGetHeight(self.context);
   unsigned char* data = CGBitmapContextGetData (self.context);
   UIColor *color = [UIColor whiteColor];
   if (data != NULL) {
        //offset locates the pixel in the data from x,y.
        //4 for 4 bytes of data per pixel, w is width of one row of data.
        int offset = 4*((contextSize.width*floorf(p.y*screenScale))+floorf(p.x*screenScale));
        int alpha =  data[offset+3];
        int red = data[offset+2];       //Note red and blue are reversed.
        int green = data[offset+1];
        int blue = data[offset+0];      //
        color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:(blue/255.0f) alpha:(alpha/255.0f)];
   }
   return color;
}

我不记得我对这段代码的想法。无论是什么,alpha通道也在另一端。当我移动alpha通道时,我也应该检查其他通道,但我没有。

如果有人决定借用此代码,您应该知道设备上的频道顺序与模拟器中的频道顺序不同。我现在正在寻找的是一种判断适当顺序的方法。