import numpy def xyz2srgb(tristimulus, scale=True): """ title:: xyz2srgb description:: This method converts a provided set of tristimulus values to sRGB. The tristimulus values are assumed to be in the range [0, 1] and computed with Illuminant D65. A non-linearity adjustment for the monitor response is applied (gamma = 2.4). (Source: http://www.brucelindbloom.com) | R-linear | | 3.2404542 -1.5371385 -0.4985314 | | X | | G-linear | = | -0.9692660 1.8760108 0.0415560 | * | Y | | B-linear | | 0.0556434 -0.2040259 1.0572252 | | Z | For [R-linear,G-linear,B-linear] <= 0.0031308 sRGB = 12.92 * RGB-linear For [R-linear,G-linear,B-linear] > 0.0031308 sRGB = ( 1 + a ) * RGB-linear^( 1 / 2.4 ) - a attributes:: tristimulus A tuple containing the tristimulus vales X, Y, and Z scale A boolean indicating whether the provided tristimulus values should be divided by 100 prior to use in the computation to make sure they are in the range [0, 1]. [default is True] returns:: A tuple containing the sRGB factors computed for the provided tristimulus values. The factors are in the range [0,1]. author:: Carl Salvaggio copyright:: Copyright (C) 2015, Rochester Institute of Technology license:: GPL version:: 1.0.0 disclaimer:: This source code is provided "as is" and without warranties as to performance or merchantability. The author and/or distributors of this source code may have made statements about this source code. Any such statements do not constitute warranties and shall not be relied on by the user in deciding whether to use this source code. This source code is provided without any express or implied warranties whatsoever. Because of the diversity of conditions and hardware under which this source code may be used, no warranty of fitness for a particular purpose is offered. The user is advised to test the source code thoroughly before relying on it. The user must assume the entire risk of using the source code. """ m = numpy.matrix([[ 3.2404542, -1.5371385, -0.4985314], [-0.9692660, 1.8760108, 0.0415560], [ 0.0556434, -0.2040259, 1.0572252]]) XYZ = numpy.matrix(tristimulus).T if scale: XYZ = XYZ / 100.0 rgbLinear = m * XYZ sRGB = rgbLinear index = numpy.where(rgbLinear <= 0.0031308) if len(index[0]) != 0: sRGB[index] = rgbLinear[index] * 12.92 index = numpy.where(rgbLinear > 0.0031308) if len(index[0]) != 0: a = 0.055 sRGB[index] = (1 + a) * numpy.array(rgbLinear[index])**(1 / 2.4) - a sRGB = numpy.clip(sRGB, 0, 1) return sRGB[0,0], sRGB[1,0], sRGB[2,0] if __name__ == '__main__': import spectral filename = '../../examples/data/real1.sp' spectrum = spectral.SpectrumFactory.create_from_file(filename) tristimulus = spectral.spectrum2xyz(spectrum) sRGB = spectral.xyz2srgb(tristimulus) print('X = {0}'.format(tristimulus[0])) print('Y = {0}'.format(tristimulus[1])) print('Z = {0}'.format(tristimulus[2])) print('') print('R = {0}'.format(sRGB[0])) print('G = {0}'.format(sRGB[1])) print('B = {0}'.format(sRGB[2]))