Is there a way to pass sRGB colors in a vertex?
Trying to set a D3D11_INPUT_ELEMENT_DESC's Format to a *_SRGB format yields an error:
D3D11 ERROR: ID3D11Device::CreateInputLayout:
Element[n]'s format (*_SRGB) cannot be used with the Input Assembler.
Of course, the vertex colors could be converted manually, but this seems like a weird special case, as I am using sRGB render targets and sRGB textures (to get proper blending), so everything else is converted between sRGB and linear spaces by hardware autmatically.
The _SRGB format 'property' is implemented in the texture lookup hardware and the blending hardware, but not in the 'input layout' hardware. This is why it doesn't work as an Input Layout format.
Related
For the past few weeks I have been debugging a very weird issue I've been having with pngs. I am building a game where the map is loaded as a png, with each individual pixel representing a specific object depending on its RGB value.
What I have noticed is that after opening my map in an editor(all editors have this problem from GIMP to photoshop to online editors) and saving it (even if no changes were made), a handful of seemingly random pixels will have their RGB values shift by a tiny amount. For example an RGB value of 255,255,255 would become 255,255,253.
I used png for my map because it is supposed to be a lossless format.
For context, I am building my game in C, using the "loadImage" function in the Raylib graphics library. It is specified in the raylib documentation that loadImage works with png files.
I have googled extensively but cannot find any information about this issue. The png compression level used when saving does not seem to make a difference. Has anyone else had this problem, or is this just a weird quirk of the png format?
I am trying to convert an RGB to the perceptually uniform color space, CIELAB. Wikipedia states:
"The RGB or CMYK values first must be transformed to a specific
absolute color space, such as sRGB or Adobe RGB. This adjustment will
be device-dependent, but the resulting data from the transform will be
device-independent, allowing data to be transformed to the CIE 1931
color space and then transformed into L*a * b*."
I know there are some straightforward transformations once converting to sRGB, but I have not found any material to go from RGB to sRGB. So, what methods exist to do such a conversion?
No, you should not go from (linear) RGB to sRGB. In fact, it is the other way round. Following are the steps:
Convert sRGB into linear RGB. sRGB image is a gamma encoded which means a camera applies gamma function pow(x, 1/2.2) onto the light signal. This sRGB is in gamma-space which is non-linear.
Now, converting linear RGB to LAB involves two steps: first is converting linear RGB to XYZ color space (this is a basic color-space). This conversion is a linear operation, i.e., matrix multiplication. This is the reason why you would need linear RGB values not sRGB. It needs to be in linear space. Finally, XYZ values are converted into LAB values through a non-linear operation which contains some standard formulas (which you don't need to be worried about).
Interesting links:
(i) Understanding sRGB and linear RGB space: http://filmicgames.com/archives/299; http://www.cambridgeincolour.com/tutorials/gamma-correction.htm
(ii) MATLAB tutorial: https://de.mathworks.com/help/vision/ref/colorspaceconversion.html
(iii) Python package: http://pydoc.net/Python/pwkit/0.2.1/pwkit.colormaps/
(iv) C code: http://svn.int64.org/viewvc/int64/colors/color.c?view=markup
(v) OpenCV does not do this sRGB to linear RGB conversion but it does the conversion inside color.cpp code (OpenCV_DIR\modules\imgproc\src\color.cpp). Check out method called initLabTabs(), there is a gamma encoding and decoding. OpenCV color conversion API: http://docs.opencv.org/3.1.0/de/d25/imgproc_color_conversions.html
I am trying to convert an array of RGB values into an array of HSV values in Matlab. I am running the following code:
pic = imread('ColoradoMountains.jpg');
pic = rgb2hsv(pic);
imwrite(pic,'pic.jpg')
But the image that gets written has completely different colors. I've been trying to set the color map to hsv, but I'm not sure if that even makes sense. Nothing on the internet comes up with my keywords, can someone please point me in the right direction?
You can specify the colormap that imwrite is supposed to use. Try this:
imwrite(pic,colormap('HSV'),'pic.png');
Here's the documentation for imwrite: http://www.mathworks.com/help/matlab/ref/imwrite.html
In Matlab you have to distinguish between an indexed image and an 3-channel image. An indexed image is a n*m*1 image where each value of the [0,1] range is associated to a colour. This association is called colour map, which could be for example a unit circle in HSV or RGB. This can be written using imwrite with the map parameter, but this is not what you want.
What you obviously want is an HSV-encoded image, which means the three rgb-channels are converted to three hsv channels. This is (as far as I know) not possible. If you take a look into the documentation of imwrite, you can see how CMYK-Encoded images are written, this is done implicit passing a n*m*4 image. Is there any of the standard file formats which supports HSV? If so I'll take a closer look at this format.
I am successfully using the cool FreeImage library to load images in various formats.
Among these, gif and png with transparency information.
After loading the images, I convert them to 32bpp using FreeImage_ConvertToRawBits. With my png images, this works fine and I can retrieve all four Red/Green/Blue/Alpha components with meaningful Alpha values.
With gif images, on the opposite, the Alpha plane remains all 255's, even though FreeImage_IsTransparent says true.
What am I missing ? Is this related to the fact that gifs are palettized ? How do I handle this ?
I found a clear answer by looking at the source code: transparency is not handled when converting a palettized image to 32 bits. The Alpha field is always set to 255.
Anyway, it is quite possible to retrieve transparency from the original palettized bitmap, pixel by pixel, knowing the value of the transparent color (FreeImage_GetTransparentIndex(dib)).
How to convert HSV color directly to CMYK color?
Bonus points for mentioning JavaScript library that does that.
I've seen only solutions that convert HSV to RGB and then RGB to CMYK.
The only solution I'm aware of is to convert to RGB as a middle tier and then convert it out to the format you want (CMYK->RGB->HSV Or HSV->RGB->CMYK) like you mentioned. I'm not sure if it's something to do with the math or another reason entirely but here is a library from the web tool kit that will at least let you get the conversion done.
A little more reading on my part turned up this:
HSL and HSV are defined purely with
reference to some RGB space, they are
not absolute color spaces: to specify
a color precisely requires reporting
not only HSL or HSV values, but also
the characteristics of the RGB space
they are based on, including the gamma
correction in use.
Source
Essentially from what I can gather HSV and HSL can't be directly converted because they're not absolute colour spaces as they need elements of RGB space that they are based upon to be meaningful. Now I'm not a color expert but I would venture that this could be why you can't directly convert between HSV and CMYK and I would assume that this is the process that goes on under the covers of conversion engines (like the web based ones) that seem to convert directly.