首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么查询时的HSB值与绘制时的HSB值不同?

为什么查询时的HSB值与绘制时的HSB值不同?
EN

Stack Overflow用户
提问于 2013-12-31 07:31:16
回答 1查看 205关注 0票数 0

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

代码语言:javascript
复制
+(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;
}

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

代码语言:javascript
复制
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。这应该产生一条足够宽的线,当我查询颜色时,我应该得到相同的颜色。查询颜色的方法如下:

代码语言:javascript
复制
-(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,但由于我对两者使用相同的上下文,我认为这不应该有什么关系。也许我需要设置一些其他的设置?

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

代码语言:javascript
复制
-(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。在我刚刚运行的过程中,创建的颜色是:

代码语言:javascript
复制
H:0.537255 S:0.598039 B:1.000000 A:1.000000

使用以下代码创建:

代码语言:javascript
复制
self.lightColor = [UIColor colorWithHue:hue saturation:saturation brightness:1.0 alpha:1.0];

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

代码语言:javascript
复制
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问题。看起来红色和蓝色是向后的。

EN

回答 1

Stack Overflow用户

发布于 2013-12-31 08:32:13

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

代码语言:javascript
复制
-(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通道时,我应该也检查其他通道,但我没有。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20849332

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档