2009-07-08 43 views
17

Có cách Cocoa Touch nào để chuyển đổi màu từ không gian màu này sang không gian màu khác không?Làm thế nào để chuyển đổi màu sắc từ một không gian màu khác?

Vào cuối của mã này:

UIColor *grey = [UIColor colorWithWhite: 0.5 alpha: 1.0]; 
CGColorRef greyRef = [grey CGColor]; 
int x = CGColorGetNumberOfComponents(greyRef); 

... x là 2.

Lý do tôi cần điều này là tôi đang cố gắng để sao chép màu sắc vào một danh sách các thành phần màu sắc cho CGGradientCreateWithColorComponents , cần tất cả các màu trong một không gian màu duy nhất. Vấn đề là màu xám là trong không gian màu xám, chứ không phải là màu RGB. (Tên thoát cho tôi vào lúc này, nhưng nó không phải là quan trọng.)

CGGradientRef createGradient(NSInteger inCount, NSArray* inColors, CGFloat* inLocations) { 
CGColorSpaceRef theColorspace = CGColorSpaceCreateDeviceRGB(); 
size_t numberOfComponents = 4; 
NSInteger colorSize = numberOfComponents * sizeof(CGFloat); 
CGFloat *theComponents = malloc(inCount * colorSize); 
CGFloat *temp = theComponents; 
for (NSInteger i = 0; i < inCount; i++) { 
    UIColor *theColor = [inColors objectAtIndex: i]; 
    CGColorRef cgColor = [theColor CGColor]; 
    const CGFloat *components = CGColorGetComponents(cgColor); 
    memmove(temp, components, colorSize); 
    temp += numberOfComponents; 
} 
CGGradientRef gradient = CGGradientCreateWithColorComponents(theColorspace, 
               theComponents, inLocations, inCount); 
CGColorSpaceRelease(theColorspace); 
free(theComponents); 
return gradient; 
} 

Tôi biết tôi có thể tìm kiếm màu sắc trong không gian màu xám và chuyển đổi chúng. Nhưng điều đó chỉ giải quyết một trường hợp. Từ tìm kiếm at this question, tôi nghĩ rằng HSB cũng được xử lý. Nhưng tôi muốn viết một số mã ở đây và không bao giờ nghĩ về nó một lần nữa, có nghĩa là hỗ trợ không chỉ là không gian màu sắc mà có bây giờ nhưng bất cứ điều gì Apple có thể hình dung thêm trong tương lai. Tôi có may mắn không?

Trả lời

7

Tôi không chắc chắn làm thế nào để tự động chuyển đổi chúng, nhưng để xác định không gian màu khác nhau mà bạn có thể nhận được CGColorSpaceModel từ của CGColorSpaceRef màu:

UIColor* color = some color; 
CGColorSpaceRef colorSpace = CGColorGetColorSpace([color CGColor]); 
CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); 

Sau đó, bạn có thể so sánh colorSpaceModel với các hằng số được định nghĩa trong CoreGraphics/CGColorSpace.h. Số điện thoại getRed:green:blue:alpha của UIColor hoạt động cho kCGColorSpaceModelRGB, trong khi getWhite:alpha hoạt động cho kCGColorSpaceModelMonochrome.

Lưu ý rằng UIColor đã được tạo bằng colorWithHue:saturation:brightness:alpha: sẽ thực sự ở trong không gian màu RGB.

+0

Đây là một câu trả lời khá hay, mặc dù bạn có thể muốn đề cập đến màu sắc HSB được đưa vào không gian màu RGB. Vì vậy, nó hoàn toàn hợp lệ để gọi 'getRed: green: blue: alpha:' trên chúng. –

+0

Hmm, có vẻ như không phải là 'kCGColorSpaceModelHSB':/ – damian

+0

Không. Chúng được ánh xạ tới không gian RGB; sử dụng phương thức RGB cho chúng. Từ các tài liệu cho 'colorWithHue: saturation: brightness: alpha:' ** Thông tin màu được đại diện bởi đối tượng [trả về] nằm trong vùng màu RGB của thiết bị. ** –

1

Một cách khác để chuyển đổi chúng là bằng cách vẽ chúng vào ngữ cảnh và cho phép đồ họa lõi thực hiện chuyển đổi cho bạn. Xem câu trả lời của tôi cho câu hỏi này:

Get RGB value from UIColor presets

+2

Chà, thật sao? Điều đó có vẻ như một ý tưởng khủng khiếp. – damian

+0

@damian Không có câu hỏi đó là xấu xí, nhưng cho đến nay như tôi biết đó là cách duy nhất đáng tin cậy hoạt động bất kể màu sắc ban đầu được tạo ra như thế nào. Cho rằng câu hỏi ban đầu đã lo lắng về "hỗ trợ không chỉ là không gian màu sắc mà có bây giờ nhưng bất cứ điều gì Apple có thể hình dung thêm trong tương lai" Tôi không thực sự thấy một lựa chọn tốt. –

+0

ThinkDifferent (tm) – damian

2

Đối với màu sắc được tạo ra sử dụng [UIColor colorWithRed:green:blue:alpha:], bạn có thể sử dụng UIColor getRed:green:blue:alpha:, được mô tả trong UIColor Class Reference. Đó là một phần của iOS 5 trở lên.

Nếu màu được tạo bằng colorWithWhite:alpha:, bạn có thể sử dụng getWhite:alpha: thay thế, được mô tả trong UIColor Class Reference.

Để xác định không gian màu nào đang được sử dụng, bạn có thể sử dụng CGColorGetColorSpace([color colorSpace]). Nhưng nó có thể dễ dàng hơn để chỉ kiểm tra kết quả của cuộc gọi phương thức, sau đó thất bại trong nỗ lực tiếp theo. Một cái gì đó như thế này:

if ([color getRed:&red green:&green blue:&blue alpha:&alpha]) { 
    // red, green and blue are all valid 
} else if if ([color getWhite:&white alpha:&alpha]) { 
    red = white; green = white; blue = white; 
} else { 
    // can't get it 
} 

Tôi không biết làm thế nào để xử lý các hằng số màu như [UIColor lightGrayColor], trừ vẽ chúng vào một bitmap tạm thời và phát hiện chúng. Một số các hằng số màu này thực sự là kết cấu; đặt cược tốt nhất của bạn có lẽ là để tránh chúng.

Nếu bạn có kế hoạch thực hiện điều này rất nhiều, nó là một sử dụng hợp lý một thể loại:

@interface UIColor(sf) 
- (BOOL)sfGetRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha; 
@end 

@implementation UIColor(sf) 
- (BOOL)sfGetRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha { 
    if ([self getRed:red green:green blue:blue alpha:alpha]) return YES; 
    CGFloat white; 
    if ([self getWhite:&white alpha:alpha]) { 
     if (red) *red = white; 
     if (green) *green = white; 
     if (blue) *blue = white; 
     return YES; 
    } 
    return NO; 
} 
@end 
+0

Câu hỏi đặc biệt yêu cầu cách chuyển đổi màu giữa các không gian màu; nếu bạn gọi phương thức này, nó có thể trả về 'NO' có nghĩa là người nhận' UIColor' đang ở một không gian màu khác với không gian màu hiện tại. Ví dụ: 'BOOL success = [[UIColor lightGrayColor] getRed: & dummy green: & dummy blue: & dummy]' trả về 'NO'. – damian

+0

Yêu cầu không gian màu tương thích, không phải cùng một không gian màu. Một số màu đơn giản là không thể chuyển đổi được. Nó sẽ có giá trị với 'colorWithWhite: alpha:'. Dường như bạn chưa đọc câu hỏi đầy đủ và bạn đã downvoted tôi đăng câu trả lời đúng. –

+0

Tôi không chắc chắn không gian màu 'tương thích' có nghĩa là gì, trong trường hợp đó. Chắc chắn một không gian màu đơn sắc là 'tương thích' với một không gian màu RGB? Tôi đã downvoted câu trả lời của bạn bởi vì, trong trường hợp của một màu đơn sắc, phương pháp bạn đề cập không chỉ không hoạt động, nhưng nó tinh tế không hoạt động và nó không rõ ràng lý do tại sao. – damian

1

Trong nhanh chóng 3 chúng ta có thể trực tiếp sử dụng

let colorSpace = uiColor.cgColor.colorSpace 
let csModel = colorSpace.model 

để có được không gian màu sắc và mô hình không gian màu từ một UIColor.

Các vấn đề liên quan