Search Unity

jpg color space

Discussion in 'Scripting' started by sylon, Jan 19, 2019.

  1. sylon

    sylon

    Joined:
    Mar 5, 2017
    Posts:
    246
    Hi guys.

    I am working on a 2D app, which is used to analyze photo's.
    I ran into a rather big problem concerning jpg color space.
    As i understand, a jpeg can have a different colorspace embedded than standard sRGB.
    Different camera's/imaging software, different color spaces.
    I have been googling around and have been reading up on the subject, but before i have to go hardcore into color space conversion, i was wondering if anyone else has encountered this and if you perhaps have some pointers on how to get this done in Unity?

    I should mention, that i am loading the images from disk into a RawImage. So i am looking for a way to detect the color space the image is in when i load it and then convert it before i show it.

    Thanks.
     
  2. sylon

    sylon

    Joined:
    Mar 5, 2017
    Posts:
    246
    An update:

    In order to be able to handle jpg color spaces, i need to Decode the jpg.
    Unity itself doesn't provide tools for this, it assumes sRGB.
    While looking for a solution, i found two things.

    1. Open source library : https://github.com/briandonahue/FluxJpeg.Core
    2. .NET JpegBitmapDecoder : https://docs.microsoft.com/en-us/do...timedia/how-to-encode-and-decode-a-jpeg-image

    So far though i, have not been able to integrate these in my project.
    The opensource library does not seem to be well documented and i have not added an external library before, so i feel i am stumbling in the dark. (i am more scripter than programmer)

    When i try to add the namespace : System.Windows.Media.Imaging so i can use the .NET JpegBitmapDecoder, i am getting this error : error CS0234: The type or namespace name 'Media' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)

    I will keep trying to integrate one of these in my project.
    Any help is more than welcome :)
     
  3. nat42

    nat42

    Joined:
    Jun 10, 2017
    Posts:
    353
    I think the build settings give a choice between .Net frameworks. The namespace referenced is in the 4.x framework but probably not in the .Net Standard 2.0 framework, perhaps you just want to change this build option?

    Dumb thought but perhaps it'd be easier if you let Unity load the JPEG and you just use a JPEG library to read the colour space without decoding the image?
     
  4. sylon

    sylon

    Joined:
    Mar 5, 2017
    Posts:
    246
    I am building with 4.x already..

    The problem is that color values are off with images that have an embedded color space when i don't convert them to RGB first.
    Before now, i was loading the image like this :

    Code (CSharp):
    1. byte[] bytes = File.ReadAllBytes(path);
    2. Texture2D texture = new Texture2D(2, 2);
    3. texture.LoadImage(bytes);
    4. rawImage.texture = texture;
    result:

    color problem.jpg
    As you can see, colors on the left are not correct.
    So i need to alter the byte[] bytes that make up the colors.
    Even if i let Unity load the image.
    I need info on it's color space to translate colors.. however i load it.
    Or am i misunderstanding you?

    When it comes to "System.Windows.Media.Imaging" not being accessible, i found something interesting.
    In order to use these libraries, you have to add the corresponding dll's to your Assets/Plugins folder.
    I have managed to get "System.Drawing" working in my code.
    Also learned a bit about using an alias to prevent conflicts.
    so instead of the usual "using System.Drawing;", you can use "using sd=System.Drawing;"
    But "System.Windows.Media.Imaging" is not so simple.
    There are several other dll's that it needs. And it get's messy when i try to add it all.

    So for now i am trying to use the Open source library : https://github.com/briandonahue/FluxJpeg.Core
    I have managed to include the code in my project and make calls to it.
    But i am a bit stuck in type differences and lack of documentation (and knowledge ;))

    Anyway, thanks for your interest. I'll keep posting my progress.
     
  5. sylon

    sylon

    Joined:
    Mar 5, 2017
    Posts:
    246
    Today is a good day :)
    I managed to fix my problem.
    In the end i chose the ImageMagick library : https://github.com/dlemstra/Magick.NET
    After previous efforts to integrate a library in my project, it all went very smoothly.
    This page : http://1darray.com/blog/2017/01/27/using-imagemagick-with-unity/ has a very useful tutorial.
    After that i had to change my code.

    Code (CSharp):
    1. using ImageMagick;
    2. .
    3. .
    4. .
    5. private void LoadExternalImage(string path)
    6. {
    7.         byte[] bytes;
    8.         using (MagickImage newMImage = new MagickImage(path))
    9.         {
    10.             // i have no idea about this profile, more interested in the second ..
    11.             newMImage.AddProfile(ImageMagick.ColorProfile.USWebCoatedSWOP);
    12.             // Adding the second profile will transform the colorspace from CMYK to RGB
    13.             newMImage.AddProfile(ImageMagick.ColorProfile.SRGB);
    14.             bytes = newMImage.ToByteArray();
    15.         }      
    16.         Texture2D texture = new Texture2D(2, 2,TextureFormat.RGB24,false,false);      
    17.         texture.LoadImage(bytes);
    18.         //
    19.         rawImage.texture = texture;
    20. }
    Colors of the loaded images are now correct.
    Hope this helps someone.
     
    dotsquid, clovisbray and Casper-Chimp like this.
  6. dotsquid

    dotsquid

    Joined:
    Aug 11, 2016
    Posts:
    224
    Hi @sylon

    Thanks for sharing your discoveries. I've just run into a similar problem. It appears that new iPhones embed Display P3 profile into saved JPGs making them look different when they're imported into Unity (or views by image viewers that ignore color spaces).

    So I wonder, did you manage to automatically detect whether the image has an embedded color profile or not? (Since there is no need for any color manipulation if the image is in good old sRGB)