0

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

+(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

嗯。现在我看它,似乎可能存在字节序问题。看起来红色和蓝色是落后的。

4

1 回答 1

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 通道时,我也应该检查其他通道,但我没有。

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

于 2013-12-31T00:32:12.637 回答