Skip to content

HueProcessor doesn't behave as expected #802

Closed

Description

@Nacimota

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am running the latest version of ImageSharp
  • I have verified if the problem exist in both DEBUG and RELEASE mode
  • I have searched open and closed issues to ensure it has not already been reported

Description

When using HueExtensions.Hue(), the resulting image does not look the way I would expect it to, based on my understanding of what hue is.

Given this example:

example

I would expect a hue shift of 180 degrees to produce something like this:

example-photoshop-180

However, ImageSharp produces this:

example-180

Have I misunderstood what this method is supposed to do? Basically I'm expecting it to behave like the Hue/Saturation dialog in Photoshop does, when you change the hue and Colorize is unchecked.

Steps to Reproduce

  1. Download and save the first image from above as example.png.
  2. Run this code:
using (var img = Image.Load("example.png"))
{
    img.Mutate(c => c.Hue(180));

    using (var stream = File.Create("example-180.png"))
    {
        img.SaveAsPng(stream);
    }
}

System Configuration

  • ImageSharp version: 1.0.0-beta0005
  • Other ImageSharp packages and versions: none
  • Environment (Operating system, version and so on):
    • Windows 10 Pro 1809 x64 v10.0.17763.194
    • Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-43-generic x86_64)
  • .NET Framework version: .NET Core 2.1

Activity

  1. Nacimota commented on Jan 6, 2019

    @Nacimota
    Author

    Okay I think I understand what's going on here. I had a dig around in the source and it pretty explicitly states that lum is preserved in the filter:

    // The matrix is set up to preserve the luminance of the image.

    I guess my question then becomes: should it, though? It doesn't seem intuitive to me, at least not as a default. Maybe we could get a filter that ignores luminosity? I don't have much experience with graphics programming so I'll have to do a lot of thought/research if I'm to create one myself.

  2. JimBobSquarePants commented on Jan 6, 2019

    @JimBobSquarePants
    Member

    Hi @Nacimota

    This is one of those situations where what Photoshop does I'd describe as wonky. Here's a fiddle demonstrating what CSS does. As you can see the output matches the behaviour there exactly which is what I would expect.

    https://jsfiddle.net/37dyftxz/

    CSS Hue rotated image

    I don't plan on adding a filter that replicates the unorthodox behaviour but if you wanted to the maths is demonstrated here.
    http://graficaobscura.com/matrix/index.html

    Hope that makes sense.

    Cheers

    James

  3. Nacimota commented on Jan 6, 2019

    @Nacimota
    Author

    Hi, @JimBobSquarePants

    Thanks for your quick reply. I think I'm just not understanding this stuff properly. One of my main issues with this hue function is that it seems to colourize grey parts of an image under certain conditions.

    So for example when I take this image:
    grey

    And run it through ImageSharp with a rotation of 90 degrees, I get this:
    grey-90

    When I use the same image and 90 degree shift in your CSS example, the image stays grey as I would expect it to. Surely if you shift the hue of a pixel with no saturation, it should remain unchanged?

  4. JimBobSquarePants commented on Jan 6, 2019

    @JimBobSquarePants
    Member

    Now that is interesting!

    Here's the source for hue rotation in Chromium. Our matrice calculation looks the same (different indices but that's due to the 1D nature of their array). I'll do some experimentation.

    https://cs.chromium.org/chromium/src/cc/paint/render_surface_filters.cc?l=72

  5. Nacimota commented on Jan 8, 2019

    @Nacimota
    Author

    After discussing this in gitter, I've been encouraged to post a couple of extra examples for clarity. Both of these comparison pictures use a 90 degree shift as well. It seems like the further you are from 180 or 0 degrees, the more incorrect the result becomes:

    rainbow-comp

    mixed

    The middle image on the bottom there is my attempt at implementing the "simple" (non-luminance-preserving) filter described on the graficaobscura page linked above.

  6. added a commit that references this issue on Jan 9, 2019
    c0ee549
  7. jsheely commented on May 16, 2022

    @jsheely

    Did anyone figure out how to do it so it works like how Photoshop does hue processing. I'm not getting any yellow.

    I'm not sure I understand how to use the Fix Colors Filters PR if that is a fix or not

  8. jsheely commented on May 17, 2022

    @jsheely

    @Nacimota Would you be able to post a function that handles the filter processing you were able to come up with?

  9. JimBobSquarePants commented on May 17, 2022

    @JimBobSquarePants
    Member

    Hey @jsheely can you please stop spamming closed issues. If you have a problem report it properly like a professional

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions