If I do not filter through an ICC profile, is CMYK to RGB conversion 1:1?
Looks like it when using color pickers like this one.
No, it is not. CMYK and RGB have a lot of colors in common, but not all. Both contain colors the other does not.
Illustrative chart:
http://static.photo.net/attachments/bboard/00Q/00QOnx-61877884.jpg
I found the theoretical answer here helpful:
From a theoretical viewpoint, there's no question that conversion from
RGB to CMYK can be completely lossless, so (for example) you can do a
round-trip conversion (RGB to CMYk, then back to RGB) and guarantee
that the result is identical to the original input.
Related
Wikipedia and plethora of online resources provide detailed and abundant help with various color space conversions from/to RGB. What I need is a straight YUV->HSL/HSV conversion.
In fact what I need is just the Hue (don't care much for the Saturation or the brightness Lightness/Value). In other words I just need to calculate the "color angle" for a given YUV color.
Code in any language would suffice, though my preference is C-style syntax.
Note that by YUV I mean specifically Y′UV, a.k.a. YCbCr (if that makes any difference).
While YUV->RGB colorspace conversion is linear (same as "can be expressed as a matrix operation") the RGB->HSL is not. Thus it is not possible to combine the two into a single operation.
Thank you Kel Solaar for confirming this for me.
For reference:
YUV(YCbCr)->RGB conversion
RGB->HSL conversion
Note that mathematically the calculation for Hue is written piecewise as the "base angle" depends on which sector the color is in and the "major color" is driven by the max(R, G, B) expression.
I think they are from the different worlds of interest. Here is a google patent
https://patents.google.com/patent/CN105847775A/en
Could someone tell me why colors with a same rgb value (for example 127, 127, 127) look the exactly same in an image using sRGB space and one using CIE RGB space? Since one is non-linear (with gamma correction) and the other one is linear (without gamma correction), I think they should look kinda different. But image I've created looks exactly the same (I used Photoshop to create the former and for the latter, I tried Photoshop, OpenGL and OpenCV).
The difference is coming when you are manipulating an image or a color (changing the brightness or the saturation of an image). This is most visible when lowering the saturation of yellow. Try it in Photoshop with RGB and with Lab mode. Do not switch to grayscale mode, because it is using luminance correction, but the saturation slider in the Adjustment>Hue/Saturation menu.
You can also see the difference when playing with my color picker (just scroll down to the full-blown example), which represents colors in the CIE Lch space (it is using CIE Lab in the background).
In the official documentation of DXGI_FORMAT, it tells us that only a format with _SRGB enumeration postfix is in sRGB color space. I thought other format without this postfix are all in the linear space. But I found a very strange behavior of format conversion function in DirectXTex library. ( You can download it from http://directxtex.codeplex.com/ )
At first, I exported a texture file as DXGI_FORMAT_R32G32B32A32_FLOAT by using NVIDIA Photoshop DDS Plugin. Then I load this file by LoadFromDDSFile() function, and convert its format to DXGI_FORMAT_R16G16B16A16_UNORM by Convert() function. (Both of these two functions are provided by DirectXTex library.)
You guess what? After the image was converted to DXGI_FORMAT_R16G16B16A16_UNORM, the brightness of all pixels were also changed, the whole image becomes brighter than before.
If I manually convert the pixel values from sRGB space to Linear space after the image was converted to DXGI_FORMAT_R16G16B16A16_UNORM format, the resultant pixel values are same as input. Therefore, I suppose that the DirectXTex library treats DXGI_FORMAT_R32G32B32A32_FLOAT as a format in linear color space, and treats DXGI_FORMAT_R16G16B16A16_UNORM as a format in sRGB color space, then it did the color space transforming from linear space to sRGB space. ( I tried to find out why the Convert() function also converts the color space, but it was implemented by WIC, and there is no source code for it. )
So, is there any bug in DirectXTex library? Or is it the real standard for DXGI_FORMATs? If there were different color spaces for some special DXGI_FORMATs, please tell me that where can I find the specification for it.
Any help will be grateful. Thanks!
By convention float RGB values are linear, and integer RGB values are gamma-compressed. There is no particular benefit to gamma-compressing floats since the reason for gamma is to use more bits where it is perceptually needed, and floats have sufficient (perhaps excessive) number of bits throughout and are already pseudo-log encoded (using the exponent). (source)
Note that the colorspace of integer RGB textures in DXGI which are not specifically *_SRGB is not sRGB, it is driver dependent, and usually has a fixed gamma of 0.5.
The DirectXTex library does appear to be behaving correctly. However, please note that you are also relying on the behavior of whatever software you use to both capture and display the DDS files. A better test for just DirectXTex is simply to do a round-trip conversion float->int->float in the library and compare the results numerically rather than visually.
I'm attempting to draw to screen with a bunch of colors that I have in YCbCr coordinates. However, all drawing libraries that I can find (Windows or cross-platform) want to specify colors in RGB and I don't want to convert and lose precision. Can anyone tell me how to do this?
Since the monitor is RGB you will have to convert the colors somewhere. If you do it yourself, or let some third party library do it for you doesn't really matter. I believe SDL lets you put YCbCr/YUV-values directly. But the colors will be converted to RGB either by software or by your graphics card on the way to the monitor.
How can I convert a grayscale value (0-255) to an RGB value/representation?
It is for using in an SVG image, which doesn't seem to come with a grayscale support, only RGB...
Note: this is not RGB -> grayscale, which is already answered in another question, e.g. Converting RGB to grayscale/intensity)
The quick and dirty approach is to repeat the grayscale intensity for each component of RGB. So, if you have grayscale 120, it translates to RGB (120, 120, 120).
This is quick and dirty because the effective luminance you get depends on the actual luminance of the R, G and B subpixels of the device that you're using.
If you have the greyscale value in the range 0..255 and want to produce a new value in the form 0x00RRGGBB, then a quick way to do this is:
int rgb = grey * 0x00010101;
or equivalent in your chosen language.
Conversion of a grayscale to RGB is simple. Simply use R = G = B = gray value. The basic idea is that color (as viewed on a monitor in terms of RGB) is an additive system.
http://en.wikipedia.org/wiki/Additive_color
Thus adding red to green yields yellow. Add in some blue to that mix in equal amounts, and you get a neutral color. Full on [red, green, blue] = [255 255 255] yields white. [0,0,0] yields monitor black. Intermediate values, when R=G=B are all equal will yield nominally neutral colors of the given level of gray.
A minor problem is depending on how you view the color, it may not be perfectly neutral. This will depend on how your monitor (or printer) is calibrated. There are interesting depths of color science we could go into from this point. I'll stop here.
Grey-scale means that all values have the same intensity. Set all channels (in RGB) equal to the the grey value and you will have the an RGB black and white image.
Woudln't setting R,G,and B to the same value (the greyscale value) for each pixel get you a correct shade of gray?
You may also take a look at my solution Faster assembly optimized way to convert RGB8 image to RGB32 image. Gray channel is simply repeated in all other channels.
The purpose was to find the fasted possible solution for conversion using x86/SSE.