Skip to content

Commit 401e797

Browse files
committed
add PickValueOrColor tool
1 parent 12071d3 commit 401e797

File tree

5 files changed

+126
-6
lines changed

5 files changed

+126
-6
lines changed

ImageM/+imagem/+app/ImagemApp.m

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@
2828

2929
% The size (diameter) of the brush (in pixels).
3030
BrushSize = 3;
31-
31+
3232
% The value used to draw the brush
3333
BrushValue = 255;
34-
34+
35+
% The color used to draw the brush in color images
36+
BrushColor = [255 255 255];
37+
3538
% History of user commands, as a cell array of strings.
3639
History = cell(0, 1);
3740
end

ImageM/+imagem/+gui/FrameMenuBuilder.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,8 @@ function buildImageFrameMenu(obj, hf)
298298

299299
addMenuItem(obj, toolsMenu, SelectTool(@Brush), 'Brush');
300300
addMenuItem(obj, toolsMenu, SelectTool(@FloodFillTool), 'Flood Fill');
301-
addMenuItem(obj, toolsMenu, PlotLabelMapCurvesFromTable(), 'Plot Curves From Labels...');
301+
addMenuItem(obj, toolsMenu, SelectTool(@PickValueOrColor), 'Pick Current Value/Color');
302+
addMenuItem(obj, toolsMenu, PlotLabelMapCurvesFromTable(), 'Plot Curves From Labels...', true);
302303
action = SelectTool(@PlotImage3DZProfile);
303304
addMenuItem(obj, toolsMenu, action, 'Plot Image3D Z-Profile');
304305
action = SelectTool(@PlotVectorImageChannels);

ImageM/+imagem/+tools/Brush.m

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,18 @@ function processCurrentPosition(obj)
7373

7474
if ~isempty(obj.PreviousPoint)
7575
% mouse moved from a previous position
76-
drawBrushLine(obj, coord, obj.PreviousPoint, iz, ic, it);
76+
if isScalarImage(img)
77+
drawBrushLine(obj, coord, obj.PreviousPoint, iz, ic, it);
78+
else
79+
drawColorBrushLine(obj, coord, obj.PreviousPoint, iz, it);
80+
end
7781
else
7882
% respond to mouse button pressed, mouse hasn't moved yet
79-
drawBrush(obj, coord, iz, ic, it);
83+
if isScalarImage(img)
84+
drawBrush(obj, coord, iz, ic, it);
85+
else
86+
drawColorBrush(obj, coord, iz, it);
87+
end
8088
end
8189

8290
obj.PreviousPoint = coord;
@@ -106,6 +114,15 @@ function drawBrushLine(obj, coord1, coord2, iz, ic, it)
106114
end
107115
end
108116

117+
function drawColorBrushLine(obj, coord1, coord2, iz, it)
118+
[x, y] = imagem.tools.Brush.intline(coord1(1), coord1(2), coord2(1), coord2(2));
119+
120+
% iterate on current line
121+
for i = 1 : length(x)
122+
drawColorBrush(obj, [x(i) y(i)], iz, it);
123+
end
124+
end
125+
109126
function drawBrush(obj, coord, iz, ic, it)
110127
doc = obj.Viewer.Doc;
111128

@@ -120,14 +137,37 @@ function drawBrush(obj, coord, iz, ic, it)
120137
y1 = max(coord(2)-bs1, 1);
121138
x2 = min(coord(1)+bs2, dim(1));
122139
y2 = min(coord(2)+bs2, dim(2));
123-
140+
124141
% iterate on brush pixels
125142
for ix = x1:x2
126143
for iy = y1:y2
127144
doc.Image.Data(ix, iy, iz, ic, it) = obj.Viewer.Gui.App.BrushValue;
128145
end
129146
end
130147
end
148+
149+
function drawColorBrush(obj, coord, iz, it)
150+
doc = obj.Viewer.Doc;
151+
152+
% brush size in each direction
153+
bs = obj.Viewer.Gui.App.BrushSize;
154+
bs1 = floor((bs-1) / 2);
155+
bs2 = ceil((bs-1) / 2);
156+
157+
% compute bounds
158+
dim = size(doc.Image);
159+
x1 = max(coord(1)-bs1, 1);
160+
y1 = max(coord(2)-bs1, 1);
161+
x2 = min(coord(1)+bs2, dim(1));
162+
y2 = min(coord(2)+bs2, dim(2));
163+
164+
% iterate on brush pixels
165+
for ix = x1:x2
166+
for iy = y1:y2
167+
doc.Image.Data(ix, iy, iz, :, it) = obj.Viewer.Gui.App.BrushColor;
168+
end
169+
end
170+
end
131171
end % methods
132172

133173
methods (Static, Access = private)

ImageM/+imagem/+tools/FloodFillTool.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ function processCurrentPosition(obj)
6767
res = floodFill(img, coord, obj.Viewer.Gui.App.BrushValue);
6868
img.Data = res.Data;
6969

70+
doc.Modified = true;
7071
updateDisplay(obj.Viewer);
7172
end
7273

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
classdef PickValueOrColor < imagem.gui.Tool
2+
% Pick the new value or color for brush or flood-fill.
3+
%
4+
% Class PickValueOrColor
5+
%
6+
% Example
7+
% PickValueOrColor
8+
%
9+
% See also
10+
%
11+
12+
% ------
13+
% Author: David Legland
14+
15+
% Created: 2020-02-11, using Matlab 9.7.0.1247435 (R2019b) Update 2
16+
% Copyright 2020 INRAE - BIA-BIBS.
17+
18+
19+
%% Properties
20+
properties
21+
end % end properties
22+
23+
24+
%% Constructor
25+
methods
26+
function obj = PickValueOrColor(parent, varargin)
27+
% Constructor for PickValueOrColor class
28+
obj = [email protected](parent, 'pickValueOrColor');
29+
end
30+
31+
end % end constructors
32+
33+
34+
%% Methods
35+
methods
36+
function onMouseButtonPressed(obj, hObject, eventdata) %#ok<INUSD>
37+
doc = currentDoc(obj);
38+
img = doc.Image;
39+
40+
if ~isScalarImage(img)
41+
return;
42+
end
43+
44+
point = get(obj.Viewer.Handles.ImageAxis, 'CurrentPoint');
45+
coord = round(pointToIndex(obj, point(1, 1:2)));
46+
47+
pos = [num2cell(coord), {1, ':'}];
48+
if isa(obj.Viewer, 'Image3DSliceViewer')
49+
pos{3} = obj.Viewer.SliceIndex;
50+
end
51+
52+
if isScalarImage(img)
53+
obj.Viewer.Gui.App.BrushValue = img.Data(pos{:});
54+
else
55+
values = img.Data(pos{:});
56+
obj.Viewer.Gui.App.BrushColor = values(:)';
57+
end
58+
59+
end
60+
61+
function index = pointToIndex(obj, point)
62+
% Converts coordinates of a point in physical dimension to image index
63+
% First element is column index, second element is row index, both are
64+
% given in floating point and no rounding is performed.
65+
doc = currentDoc(obj);
66+
img = doc.Image;
67+
spacing = img.Spacing(1:2);
68+
origin = img.Origin(1:2);
69+
index = (point - origin) ./ spacing + 1;
70+
end
71+
72+
end % end methods
73+
74+
end % end classdef
75+

0 commit comments

Comments
 (0)