And here's the fix on my side: https://github.com/OpenImageIO/oiio/pull/2122

But the expedient workaround for you is to not restrict the channels for either 
the read or the resample. Just let the jpeg writer do its job, it will drop the 
alpha automatically.

        -- lg


> On Dec 31, 2018, at 11:25 PM, Larry Gritz <[email protected]> wrote:
> 
> This had me stumped for hours! And it revealed a very subtle bug in OIIO's 
> reading of TIFF images when restricting the channel range.
> 
> 
>> pixels = sourceImg.read_image(0, 3, oiio.UINT8)
> 
> Here, you are reading just the first 3 channels of an RGBA image. Seems sane, 
> except that this is a peculiar TIFF file -- the metadata says it's 
> "unassociated alpha" (that means that the color values are not yet 
> "premultiplied" by the alpha). Since OIIO assumes all app-side buffers should 
> be premultiplied, it does it for you by multiplying the color channels by the 
> alpha channel.
> 
> Oh ho, except that you excluded the alpha channel from the read!  Oops.  So 
> the RGB values get multiplied by some bogus alpha values, garbage (probably, 
> actually, the red value from the next pixel).
> 
> I'm working on a true fix -- the read_xxx() functions that take channel 
> ranges should skip the automatic premult if the alpha channel was not among 
> those read.
> 
> In the mean time, just read all the channels, and I think you'll be fine. 
> There's no harm calling ImageBuf.write("blah.jpg") if the buf has 4 
> channels... since JPEG only supports 3, it knows to just write RGB and ignore 
> the alpha.
> 
> (Also make resizedImageSpec have 4 channels. The resample() function requires 
> that both source and dest images have the same number of channels.)
> 
> 
> As an aside, I also want to note that this sequence:
> 
>> sourceImg = ImageInput.open(sourcePath)
>> spec = sourceImg.spec()
>>  
>> pixels = sourceImg.read_image(0, 3, oiio.UINT8)
>>  
>> sourceBufSpec = ImageSpec(spec.width, spec.height, 3, oiio.UINT8)
>> sourceBuf = ImageBuf(sourceBufSpec)
>> sourceBuf.set_pixels(oiio.ROI.All, pixels)
> 
> Is much more complicated than it needs to be. If you're just trying to put 
> things into an ImageBuf, you don't need the ImageInput, the read_image, or 
> the set_pixels. That whole thing can be collapsed to:
> 
>> sourceBuf = ImageBuf(sourcePath)
>> spec = sourceBuf.spec()
> 
> 
> And finally, I would eliminate these lines entirely:
> 
>> # Set input colorspace to linear if converting EXR file
>> if sourcePath.split('.')[-1] == 'exr':
>>     ImageBufAlgo.colorconvert(resizedBuf, resizedBuf, 'linear', 'sRGB')
> 
> That doesn't really make any sense. Just remove those lines. You want to 
> convert to sRGB before outputting to JPEG, but there's no reason to convert 
> out of linear just because it was originally exr.
> 
>       -- lg
> 
> 
>> On Dec 31, 2018, at 1:05 PM, Renaud Talon <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> Hi Larry, thanks a bunch for your help.
>>  
>> I tried the code you sent me which attempts to read the colorspace of the 
>> input image and the result is a now a brighter and desaturated image.
>> I uploaded the tiff image I’m using as a source so hopefully you can see the 
>> same result on your end.
>> 
>> <image001.jpg>
>>  
>> Test Tiff image:
>> http://s000.tinyupload.com/?file_id=10327734964867955756 
>> <http://s000.tinyupload.com/index.php?file_id=10327734964867955756>
>>  
>>  
>> Updated Code Sample:
>>  
>> import sys
>>  
>> from OpenImageIO import OpenImageIO as oiio
>> from OpenImageIO import ImageBufAlgo, ImageBuf, ImageSpec, ImageInput
>>  
>>  
>> sourcePath = "C:/temp/ataafm_diff_v001.1005.tif"
>> destImgPath = "C:/temp/test_oiio.jpg"
>>  
>> sourceImg = ImageInput.open(sourcePath)
>> spec = sourceImg.spec()
>>  
>> pixels = sourceImg.read_image(0, 3, oiio.UINT8)
>>  
>> sourceBufSpec = ImageSpec(spec.width, spec.height, 3, oiio.UINT8)
>> sourceBuf = ImageBuf(sourceBufSpec)
>> sourceBuf.set_pixels(oiio.ROI.All, pixels)
>>  
>> resizedImgSpec = ImageSpec(int(120), int(120), 3, oiio.UINT8)
>> resizedBuf = ImageBuf(resizedImgSpec)
>>  
>> ImageBufAlgo.resample(resizedBuf, sourceBuf)
>>  
>> # Set input colorspace to linear if converting EXR file
>> if sourcePath.split('.')[-1] == 'exr':
>>     ImageBufAlgo.colorconvert(resizedBuf, resizedBuf, 'linear', 'sRGB')
>>  
>> if destImgPath.split('.')[-1] == 'jpg':
>>     # query input color space, presume linear if there is no such metadata
>>     srcColSpace = sourceImg.spec().get_string_attribute('oiio:ColorSpace', 
>> 'linear')
>>     ImageBufAlgo.colorconvert(resizedBuf, resizedBuf, srcColSpace, 'sRGB')
>>  
>> resizedBuf.write(destImgPath)
>>  
>>  
>>  
>> From: Renaud Talon 
>> Sent: Friday, December 28, 2018 1:10 PM
>> To: 'Larry Gritz' <[email protected] <mailto:[email protected]>>; 
>> OpenImageIO developers <[email protected] 
>> <mailto:[email protected]>>; [email protected] 
>> <mailto:[email protected]>
>> Subject: RE: [Oiio-dev] Tiff image conversion to jpg color shift issue
>>  
>> oiiotool.exe C:\temp\ataafm_diff_v001.1005.tif -resize 120x120 -o 
>> c:/temp/test_oiio_tool.jpg
>>  
>> From: Larry Gritz <[email protected] <mailto:[email protected]>> 
>> Sent: Friday, December 28, 2018 1:05 PM
>> To: OpenImageIO developers <[email protected] 
>> <mailto:[email protected]>>; Renaud Talon 
>> <[email protected] <mailto:[email protected]>>; 
>> [email protected] <mailto:[email protected]>
>> Subject: Re: [Oiio-dev] Tiff image conversion to jpg color shift issue
>>  
>> What oiiotool command line did you use when it worked as expected?
>> 
>> 
>> On December 28, 2018 12:36:04 PM PST, Renaud Talon <[email protected] 
>> <mailto:[email protected]>> wrote:
>> Hi Larry,
>>  
>> I’m having a problem when making thumbnails from tiff images where the 
>> results image is coming out darker and less saturated than the source.
>> When using oiiotool.exe it results in a proper output but the issue happens 
>> when I do the conversion myself from the python API.
>> Any idea why this is happening ?
>> Thanks !
>>  
>> Trimmed down code:
>> 
>> from OpenImageIO import OpenImageIO as oiio
>> from OpenImageIO.OpenImageIO import ImageBufAlgo, ImageBuf, ImageSpec, 
>> ImageInput
>>  
>>  
>> sourceImgPath = "C:/temp/ataafm_diff_v001.1005.tif"
>>  
>> sourceImg = ImageInput.open(sourceImgPath)
>> spec = sourceImg.spec()
>>  
>> pixels = sourceImg.read_image(0, 3, oiio.UINT8)
>>  
>> sourceBufSpec = ImageSpec(spec.width, spec.height, 3, oiio.UINT8)
>> sourceBuf = ImageBuf(sourceBufSpec)
>> sourceBuf.set_pixels(oiio.ROI.All, pixels)
>>  
>> resizedImgSpec = ImageSpec(int(120), int(120), 3, oiio.UINT8)
>> resizedBuf = ImageBuf(resizedImgSpec)
>>  
>> ImageBufAlgo.resample(resizedBuf, sourceBuf)
>>  
>> # Set input colorspace to linear if converting EXR file
>> if sourceImgPath.split('.')[-1] == 'exr':
>>     ImageBufAlgo.colorconvert(resizedBuf, resizedBuf, 'linear', 'sRGB')
>>  
>> resizedBuf.write('C:/temp/test_oiio.jpg')
>>  
>>  
>> 
>>  
>> Renaud
>> 
>> -- 
>> Larry Gritz
>> [email protected] <mailto:[email protected]>
> --
> Larry Gritz
> [email protected] <mailto:[email protected]>
> 
> 
> 
> 
> _______________________________________________
> Oiio-dev mailing list
> [email protected]
> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org

--
Larry Gritz
[email protected]




_______________________________________________
Oiio-dev mailing list
[email protected]
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org

Reply via email to