Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persistent color picker tool / Lockable Color Picker #1812

Closed
Beep6581 opened this issue Aug 11, 2015 · 90 comments
Closed

Persistent color picker tool / Lockable Color Picker #1812

Beep6581 opened this issue Aug 11, 2015 · 90 comments
Assignees
Labels
type: enhancement Something could be better than it currently is

Comments

@Beep6581
Copy link
Owner

Originally reported on Google Code with ID 1828

When you hover over the preview, RT shows RGB, HSV and Lab pixel values. I would like
to be able to click and leave the picker there, so that I can see the values change
in real-time as I adjust a slider or curve.

Right-click on preview to place a sampler. The gtk-find icon could be centered over
the sampled pixel.
Click a sampler to remove it.
Click and drag a sampler to move it around.

Reported by entertheyoni on 2013-04-05 13:21:45

@Beep6581 Beep6581 self-assigned this Aug 11, 2015
@Beep6581
Copy link
Owner Author

I'd like it too.

And an extension to "Area Sampler" a rectangle like that in WB picker. Both for real
time and persistent pickers. 
Point sampler makes consistent metering difficult especially on noisy areas.

Reported by iliasgiarimis on 2013-04-05 19:25:58

@kazah7
Copy link

kazah7 commented Feb 15, 2016

That would be useful! It is in darktable, sometimes i use it to equalize skin tones between people.

@Beep6581 Beep6581 added the type: enhancement Something could be better than it currently is label May 22, 2016
@Hombre57
Copy link
Collaborator

I don't know how you would use this feature in practice, but I'd like to know if it has to be a tool (stored in the pp3) or just a volatile tool that will reset itself at each image loading ?

@heckflosse
Copy link
Collaborator

That would be useful feature. 👍 if the impact on processing time in gui is low. If there are changes in gui processing pipeline which decrease performance I will take a look to solve them.

Ingo

@Hombre57
Copy link
Collaborator

thanks for the offer @heckflosse . The tool will only look at the image data at the end of the pipeline, so there shouldn't be any impact on the processing. Any comment for the pp3 vs volatile choice ?

@heckflosse
Copy link
Collaborator

@Hombre57 I think volatile would be sufficient

@Hombre57
Copy link
Collaborator

Hombre57 commented Sep 1, 2016

@Hombre57 I think volatile would be sufficient

I think so too. And doing a Tool (i.e. saved in the pp3) for this would add much work in fact.

@Beep6581
Copy link
Owner Author

Beep6581 commented Sep 1, 2016

I'd like to know if it has to be a tool (stored in the pp3) or just a volatile tool that will reset itself at each image loading ?

Volatile, shouldn't touch the PP3.

Let's say I want to make some region a specific hue, I would just drop the picker on that spot and move some widget such as the HH curve, until the hue is reached. The pickers could be just little circles "o" over the preview, and clicking a circle removes it. Opening the next photo would also remove all of the circles, the same as with the little "Detail" zoom windows.

@Hombre57
Copy link
Collaborator

Hombre57 commented Sep 5, 2016

Ok. So here is my plan :

I'd add a new button in the top toolbar of the Editor panel, next to the Hand or Straighten tool. When pressed, you'll only able to add/move/resize/delete the color pickers. When unpressed, everything will remain visible bu you won't be able to interact with the pickers anymore.

The color picker will be a square shape (I know that a circle would be better, but that may be done later) with the detected color displayed inside, of a modifiable size and with values displayed below. I know that it will hide part of the context next to the picker, but is this really important ? We have to find some place to display the values anyway... You'll be able to set the font size in Preferences, but the font shape will be the same than the Navigator tool.

The expected behavior is (when in Color Picker mode) :

  • [EDITED] add a new picker or move an existing one with LMB (Left Mouse Button, and so on...)
  • delete a single picker by hovering it and pressing RMB
  • delete all pickers by hovering one picker and pressing Ctrl+Shift+RMB
  • go back to the Navigator tool by right clicking outside of any picker

I think it will be a good starting point.

I'll start this patch this week, beside finishing the Soft-proofing patch (with the help of Marty if he's okay to help).

@Hombre57
Copy link
Collaborator

Hombre57 commented Sep 5, 2016

And... should we be able to show/hide the pickers in some ways ? Then I'd suggest to right click on the Color Picker button, with some obvious logic.

I know that this is not intuitive, but a tooltip will be there to help. For the on preview behavior, users will have to RTFM or explore by themselves.

@heckflosse
Copy link
Collaborator

@Hombre57 For the circle shape maybe I can point you to the code of focus mask (where the shape also was a square before I made circles)

Ingo

@Hombre57
Copy link
Collaborator

Hombre57 commented Sep 6, 2016

@heckflosse I didn't even knew that the focus mask (for focus peaking ???) uses circles 😅 . That may help depending on what it really is. I need an algorithm to read values inside a defined circle size, I guess that I'll find something using polar coordinates...

@heckflosse
Copy link
Collaborator

@Hombre57 focus mask uses a very simple (and fast) approach to draw small circles. Maybe you can use this too.

@Hombre57 Hombre57 assigned Hombre57 and unassigned Beep6581 Sep 6, 2016
@Hombre57
Copy link
Collaborator

Just a comment to say that the patch is progressing well. It's more difficult than expected but I've found a solution for every problem I think. Still 20% of work to be done, it won't be finished by the end of the month but I'm confident for a mid-october first release (or before if I have more free time). It also depend on the requirment of the Soft-proofing branch for RT5 that seem to have a higher priority, see issue #3300.

@Hombre57
Copy link
Collaborator

Hombre57 commented Sep 29, 2016

For those of you who are interested in this feature, I've create a new lockable-color-picker branch with preliminary support. It's still Work In Progress but should be already usable.

The displayed values are those from the internal Working Space image (have to check that...) i.e. not color corrected. If you use this tool to compare different images, this should not be a problem.

What's already working fine :

  1. Entering the Lockable Picker mode through the new dedicated Tool Mode on the right of the WB tool at the top of the Editor panel.
  2. When in Lockable Picker mode, you can create new pickers by simply clicking in the image preview. There's a bug that prevent the picker to show the color at the first click, you have to drag it a little bite to see the values. This will be solved. It also mean that you won't be able to pan the image in this mode, but zooming in/out works.
  3. You can right click over a picker to delete it
  4. You can right click over a picker while pressing CTRL+SHIFT to delete ALL pickers
  5. Right clicking outside of any picker will end the Lockable Picker mode and you'll return to the Hand mode.
  6. You can right click over the Lockable Picker button (in the top toolbar) to eventually exit this mode (if active) and switch the show/hide state of the pickers.
  7. You can set the font in Preference, first tab.

If you create a picker in a Detail window, it should be shown in its Detail window only. This doesn't work for now, the picker become black when dragged outside it. Will be solved soon.

Other flaws to solve and add features to add (but the most part is done) :

  1. When in Object Editing mode (e.g. with the Gradient tool), activating the Lockable Pickers should exit the Gradient "on preview" widgets. This doesn't work yet.
  2. You should be able to switch from RGB to HSV display, doesn't work yet
  3. Sometimes, while dragging the picker, it disappears briefly (flashing). I don't know why and can take time to find this bug, but it shouldn't be too cumbersome.
  4. If the picker disappear because it's crossing the Preview's border or the Detail window's border while panning, bringing it back in the window doesn't make it appear again, so just zoom in/out and it should display again. Of course this will be solved.

Don't care about reporting bug as of now (unless you experience a crash), I have to finish it first then the testing phase can start.

@Hombre57
Copy link
Collaborator

Oh, I forgot to add : the user should also be able to increase the picker size. Not done yet.

Furthermore, as you can see, the picker has a fixed size whatever your zoom rate is. It means that you can collect more data by zooming out, thanks to the scaling.

@heckflosse
Copy link
Collaborator

@Hombre57

The Navigator and the the Color Pickers are both showing the same value, so this branch has no issue. What you see in the circle is the color from cropimgtrue (that you don't see otherwise), which is different from cropimg (see rtgui/crophandler.cc, line 396 and rtengine/dcrop.cc line 975. If you think that the color are wrong, please open a new issue.

May I also post a patch instead of creating a new issue ;-) ?

@Hombre57
Copy link
Collaborator

Hombre57 commented Oct 5, 2016

@heckflosse In SETM, opening a new image while in Color Picker mode will disable this mode, so when double clicking on a new image I have to wait that the image is displayed, then press 'z', then click on the Color Picker tool, then place a picker and drag it -> no crash.

I'm using a debug build, and Gtk3.22 compiled with Gcc 6.xx. I can't say better.

May I also post a patch instead of creating a new issue ;-) ?

...ok...

here is a patch for the picker becomes black when zooming in bug

Thanks, works fine !

@heckflosse
Copy link
Collaborator

@Hombre57 I still can reproduce it with Debug and Release builds on Win7/64. @Beep6581 also can reproduce the crash on Linux, means that my howto is missing something to reproduce it if it doesn't crash on your side. We have to investigate further...

Ingo

@heckflosse
Copy link
Collaborator

heckflosse commented Oct 5, 2016

@Hombre57

Here is a quick and dirty patch to preview correct colour inside the circle

Edit: The patch does not include the patch for the picker becomes black when zooming in bug. You have to combine them

@Hombre57
Copy link
Collaborator

Hombre57 commented Oct 5, 2016

@heckflosse With the BT you posted above, can you see if ipc is null or non null but pointing to a freed object ? In the first case, I could check ipc.

@Floessie Should I protect the IPC from being accessed asynchronously by the GUI with a Mutex ? On line 789 of editorpanel.cc, ipc is set to null, but that might not be sufficient ?

@Hombre57
Copy link
Collaborator

Hombre57 commented Oct 5, 2016

@heckflosse

Here is a quick and dirty patch to preview correct colour inside the circle

Well, I think we didn't understood ourselves. I consider seeing the color corresponding to the displayed RGB values as correct (and it's true that they can be very different than what's displayed in the preview). You consider that whatever the displayed RGB values are, we should display the preview's color, it would be a color mismatch for me.

[Time to go to sleep, we'll continue discussion tomorrow, good night]

@heckflosse
Copy link
Collaborator

heckflosse commented Oct 5, 2016

@Hombre57

I consider seeing the color corresponding to the displayed RGB values as correct

But what you did by doing this is displaying it in preview in a wrong colour space. Assume working profile is ProphotoRgb, then the rgb values (in working profile) are very different to e.g. srgb. But simply using the ProhotoRgb values in preview (which in my assumption is sRGB) leads to a colour inside the circle which is of no use (at least of no use I'm aware of)

Imho we should display the correct values (for working profile or output profile), but in preview the colour of the circle should match the preview colour behind it.

@Floessie
Copy link
Collaborator

Floessie commented Oct 6, 2016

@Hombre57

I can reproduce it with a debug build on Debian Stretch with GCC 6.1.1 and GTK 2.24.

Should I protect the IPC from being accessed asynchronously by the GUI with a Mutex ? On line 789 of editorpanel.cc, ipc is set to null, but that might not be sufficient?

No, it's rather an unregistered callback like the one in #3048.

@Floessie
Copy link
Collaborator

Floessie commented Oct 6, 2016

@Hombre57 Don't look any further, I think I've found it. Preparing a patch...

@Floessie
Copy link
Collaborator

Floessie commented Oct 6, 2016

The problem was, that although ImageArea::ipc was reset in ImageArea::setImProcCoordinator(), CropWindow::ipc wasn't. Instead of propagating it to CropWindow, I've completely removed it there and added ImageArea::getImProcCoordinator(). Hopefully this won't break anything, but if so, one could still choose to propagate it.

HTH
Flössie

diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc
index df9cb9f..8b3210f 100644
--- a/rtgui/cropwindow.cc
+++ b/rtgui/cropwindow.cc
@@ -66,13 +66,13 @@ ZoomStep zoomSteps[] = {
 #define MAXZOOMSTEPS 20
 #define ZOOM11INDEX  13

-CropWindow::CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_, bool isLowUpdatePriority_, bool isDetailWindow)
+CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDetailWindow)
     : ObjectMOBuffer(parent), state(SNormal), press_x(0), press_y(0), action_x(0), action_y(0), pickedObject(-1), pickModifierKey(0), rot_deg(0), onResizeArea(false), deleted(false),
       fitZoomEnabled(true), fitZoom(false), isLowUpdatePriority(isLowUpdatePriority_), hoveredPicker(nullptr), cropLabel(Glib::ustring("100%")),
       backColor(options.bgcolor), decorated(true), isFlawnOver(false), titleHeight(30), sideBorderWidth(3), lowerBorderWidth(3),
       upperBorderWidth(1), sepWidth(2), xpos(30), ypos(30), width(0), height(0), imgAreaX(0), imgAreaY(0), imgAreaW(0), imgAreaH(0),
       imgX(-1), imgY(-1), imgW(1), imgH(1), iarea(parent), cropZoom(0), zoomVersion(0), exposeVersion(0), cropgl(NULL),
-      pmlistener(NULL), pmhlistener(NULL), observedCropWin(NULL), ipc(ipc_)
+      pmlistener(NULL), pmhlistener(NULL), observedCropWin(NULL)
 {
     Glib::RefPtr<Pango::Context> context = parent->get_pango_context () ;
     Pango::FontDescription fontd = context->get_font_description ();
@@ -110,7 +110,7 @@ CropWindow::CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_,
     minWidth = bsw + iw + 2 * sideBorderWidth;

     cropHandler.setDisplayHandler(this);
-    cropHandler.newImage (ipc_, isDetailWindow);
+    cropHandler.newImage (parent->getImProcCoordinator(), isDetailWindow);
 }

 CropWindow::~CropWindow ()
@@ -904,13 +904,13 @@ void CropWindow::pointerMoved (int bstate, int x, int y)
         screenCoordToImage (x, y, imgPos.x, imgPos.y);
         if (imgPos.x < 0) {
             imgPos.x = 0;
-        }else if (imgPos.x >= ipc->getFullWidth()) {
-            imgPos.x = ipc->getFullWidth()-1;
+        }else if (imgPos.x >= iarea->getImProcCoordinator()->getFullWidth()) {
+            imgPos.x = iarea->getImProcCoordinator()->getFullWidth()-1;
         }
         if (imgPos.y < 0) {
             imgPos.y = 0;
-        }else if (imgPos.y >= ipc->getFullHeight()) {
-            imgPos.y = ipc->getFullHeight()-1;
+        }else if (imgPos.y >= iarea->getImProcCoordinator()->getFullHeight()) {
+            imgPos.y = iarea->getImProcCoordinator()->getFullHeight()-1;
         }
         imageCoordToCropImage(imgPos.x, imgPos.y, cropPos.x, cropPos.y);
         float r=0.f, g=0.f, b=0.f;
@@ -2056,10 +2056,10 @@ void CropWindow::buttonPressed (LWButton* button, int actionCode, void* actionDa
     } else if (button == bZoom100) { // zoom 100
         zoom11 ();
     } else if (button == bClose) { // close
-        if(ipc->updateTryLock()) {
+        if(iarea->getImProcCoordinator()->updateTryLock()) {
             deleted = true;
             iarea->cropWindowClosed (this);
-            ipc->updateUnLock();
+            iarea->getImProcCoordinator()->updateUnLock();
         }
     }
 }
diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h
index 089fcb8..5796a78 100644
--- a/rtgui/cropwindow.h
+++ b/rtgui/cropwindow.h
@@ -94,7 +94,6 @@ class CropWindow : public LWButtonListener, public CropDisplayHandler, public Ed
     std::list<CropWindowListener*> listeners;

     CropWindow* observedCropWin;  // Pointer to the currently active detail CropWindow
-    rtengine::StagedImageProcessor* ipc;

     bool onArea                    (CursorArea a, int x, int y);
     void updateCursor              (int x, int y);
@@ -113,7 +112,7 @@ class CropWindow : public LWButtonListener, public CropDisplayHandler, public Ed

 public:
     CropHandler cropHandler;
-    CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_, bool isLowUpdatePriority_, bool isDetailWindow);
+    CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDetailWindow);
     ~CropWindow ();

     void setDecorated       (bool decorated)
diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc
index c09051e..125968b 100644
--- a/rtgui/imagearea.cc
+++ b/rtgui/imagearea.cc
@@ -88,7 +88,7 @@ void ImageArea::on_resized (Gtk::Allocation& req)
 {
     if (ipc && get_width() > 1) { // sometimes on_resize is called in some init state, causing wrong sizes
         if (!mainCropWindow) {
-            mainCropWindow = new CropWindow (this, ipc, false, false);
+            mainCropWindow = new CropWindow (this, false, false);
             mainCropWindow->setDecorated (false);
             mainCropWindow->setFitZoomEnabled (true);
             mainCropWindow->addCropWindowListener (this);
@@ -106,7 +106,12 @@ void ImageArea::on_resized (Gtk::Allocation& req)
     }
 }

-void ImageArea::setImProcCoordinator (rtengine::StagedImageProcessor* ipc_)
+rtengine::StagedImageProcessor* ImageArea::getImProcCoordinator() const
+{
+    return ipc;
+}
+
+void ImageArea::setImProcCoordinator(rtengine::StagedImageProcessor* ipc_)
 {
     if( !ipc_ ) {
         focusGrabber = NULL;
@@ -398,7 +403,7 @@ void ImageArea::addCropWindow ()
         return;    // if called but no image is loaded, it would crash
     }

-    CropWindow* cw = new CropWindow (this, ipc, true, true);
+    CropWindow* cw = new CropWindow (this, true, true);
     cw->zoom11();
     cw->setCropGUIListener (cropgl);
     cw->setPointerMotionListener (pmlistener);
diff --git a/rtgui/imagearea.h b/rtgui/imagearea.h
index deabe8a..71d4007 100644
--- a/rtgui/imagearea.h
+++ b/rtgui/imagearea.h
@@ -73,7 +73,8 @@ public:
     ImageArea (ImageAreaPanel* p);
     ~ImageArea ();

-    void setImProcCoordinator (rtengine::StagedImageProcessor* ipc_);
+    rtengine::StagedImageProcessor* getImProcCoordinator() const;
+    void setImProcCoordinator(rtengine::StagedImageProcessor* ipc_);
     void setPreviewModePanel(PreviewModePanel* previewModePanel_)
     {
         previewModePanel = previewModePanel_;

@Hombre57
Copy link
Collaborator

Hombre57 commented Oct 6, 2016

@Floessie Great that you fixed the bug, I'll let @heckflosse and @Beep6581 test it, since I didn't experienced it.

@heckflosse

But what you did by doing this is displaying it in preview in a wrong colour space. Assume working profile is ProphotoRgb, then the rgb values (in working profile) are very different to e.g. srgb. But simply using the ProhotoRgb values in preview (which in my assumption is sRGB) leads to a colour inside the circle which is of no use (at least of no use I'm aware of)

I understand better now. I'll integrate your patch then.

@heckflosse
Copy link
Collaborator

@Floessie wrote

The problem was...

Your patch builds fine and fixes the crash. Thank you!

@heckflosse
Copy link
Collaborator

@Hombre57

I understand better now. I'll integrate your patch then

Please wait. I just detected that it doesn't always work correctly

@heckflosse
Copy link
Collaborator

@Hombre57 I updated the link from above with the corrected code

@Hombre57
Copy link
Collaborator

Hombre57 commented Oct 6, 2016

Last commit added the bugfix from @heckflosse and @Floessie (thanks a lot for the help guys) + the request from @Beep6581 .

Please test for new bugs, but feature wise it's complete now.

@Hombre57
Copy link
Collaborator

Hombre57 commented Oct 7, 2016

Added a bugfix and code simplification in a new commit.

@Floessie
Copy link
Collaborator

Floessie commented Oct 7, 2016

@Hombre57 Tip: If you add "#1812" somewhere in your commit message (I usually append it in brackets on the headline), your commits will automagically appear here. That's a cool GitHub feature and helps us to review them "in place". 😃

@Hombre57
Copy link
Collaborator

Hombre57 commented Oct 7, 2016

@Floessie I tend to forget that kind of useful things. Will do next time.

@heckflosse
Copy link
Collaborator

@Hombre57 Works fine here. Thank you 👍

There's one (minor) issue remaining:
When I place a picker in a detail window and then move that detail window, the picker disappears until a redraw is triggered (by zooming in/out or switch to another application and back ...)

Example

@heckflosse
Copy link
Collaborator

@Hombre57 Great, works fine now

@heckflosse
Copy link
Collaborator

@Hombre57 I found another issue

Hombre57 added a commit that referenced this issue Oct 7, 2016
when the Color Picker mode is off.

see issue #1812
@heckflosse
Copy link
Collaborator

Imho now it's right to merge :)

@Hombre57
Copy link
Collaborator

Hombre57 commented Oct 8, 2016

Done ! Thanks for the debugging :)

@Hombre57 Hombre57 closed this as completed Oct 8, 2016
@heckflosse
Copy link
Collaborator

@Hombre57 Thank you for implementing this great tool. I especially like it in combination with hsv curves to partly desaturate an image. Though for this use case it would be an improvement to show the hue value at the x-axis of hsv curve. But that's a different issue.

Well done!

Ingo

@PhilBaz
Copy link

PhilBaz commented Oct 11, 2016

Yes, i also wanted to say thanks for your efforts @Hombre57. The tool was implemented very nicely and it will be a pleasure to use.

Looking forward to seeing it in the official release.....

Anyone have a clue when that might be?

@Floessie
Copy link
Collaborator

@PhilBaz

Anyone have a clue when that might be?

We are in the process of releasing RT5, which should be due by the end of the month. As the lockable color pickers have already been merged to master, they will be part of that release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement Something could be better than it currently is
Projects
None yet
Development

No branches or pull requests

8 participants