Mercurial > octave
comparison scripts/image/image.m @ 17692:38cf56b77274
Overhaul image, imagesc to use newplot and support low-level invocation form.
* scripts/image/image.m: New variable do_new indicates high-level calling form.
For high-level invocation, call newplot before __img__. Correct linearity check
if vectors are reversed (high-to-low values). Only apply image properties to axes
if doing a high-level invocation.
* scripts/image/imagesc.m: New variable do_new indicates high-level calling form.
Delete subfunction __imagesc__ and incorporate minimal amount of code into imagesc.
Only apply climits for high-level invocation.
author | Rik <rik@octave.org> |
---|---|
date | Fri, 18 Oct 2013 16:27:44 -0700 |
parents | dd8db3f1c1da |
children | d63878346099 |
comparison
equal
deleted
inserted
replaced
17691:8a54a481ecb5 | 17692:38cf56b77274 |
---|---|
63 | 63 |
64 function h = image (varargin) | 64 function h = image (varargin) |
65 | 65 |
66 [hax, varargin, nargin] = __plt_get_axis_arg__ ("image", varargin{:}); | 66 [hax, varargin, nargin] = __plt_get_axis_arg__ ("image", varargin{:}); |
67 | 67 |
68 if (isempty (hax)) | |
69 hax = gca (); | |
70 endif | |
71 | |
72 chararg = find (cellfun ("isclass", varargin, "char"), 1, "first"); | 68 chararg = find (cellfun ("isclass", varargin, "char"), 1, "first"); |
73 | 69 |
74 if (nargin == 0 || chararg == 1) | 70 do_new = true; |
71 if (nargin == 0) | |
75 img = imread ("default.img"); | 72 img = imread ("default.img"); |
76 x = y = []; | 73 x = y = []; |
74 elseif (chararg == 1) | |
75 ## Low-Level syntax | |
76 do_new = false; | |
77 x = y = img = []; | |
78 idx = find (strcmpi (varargin, "cdata"), 1); | |
79 if (idx) | |
80 img = varargin{idx+1}; | |
81 varargin(idx:idx+1) = []; | |
82 endif | |
83 idx = find (strcmpi (varargin, "xdata"), 1); | |
84 if (idx) | |
85 x = varargin{idx+1}; | |
86 varargin(idx:idx+1) = []; | |
87 endif | |
88 idx = find (strcmpi (varargin, "ydata"), 1); | |
89 if (idx) | |
90 y = varargin{idx+1}; | |
91 varargin(idx:idx+1) = []; | |
92 endif | |
77 elseif (nargin == 1 || chararg == 2) | 93 elseif (nargin == 1 || chararg == 2) |
78 img = varargin{1}; | 94 img = varargin{1}; |
79 x = y = []; | 95 x = y = []; |
80 elseif (nargin == 2 || chararg == 3) | 96 elseif (nargin == 2 || chararg == 3) |
81 print_usage (); | 97 print_usage (); |
83 x = varargin{1}; | 99 x = varargin{1}; |
84 y = varargin{2}; | 100 y = varargin{2}; |
85 img = varargin{3}; | 101 img = varargin{3}; |
86 chararg = 4; | 102 chararg = 4; |
87 endif | 103 endif |
88 | 104 |
89 htmp = __img__ (hax, x, y, img, varargin{chararg:end}); | 105 oldfig = []; |
90 set (hax, "layer", "top"); | 106 if (! isempty (hax)) |
107 oldfig = get (0, "currentfigure"); | |
108 endif | |
109 unwind_protect | |
110 if (do_new) | |
111 hax = newplot (hax); | |
112 elseif (isempty (hax)) | |
113 hax = gca (); | |
114 endif | |
115 | |
116 htmp = __img__ (hax, do_new, x, y, img, varargin{chararg:end}); | |
117 | |
118 unwind_protect_cleanup | |
119 if (! isempty (oldfig)) | |
120 set (0, "currentfigure", oldfig); | |
121 endif | |
122 end_unwind_protect | |
91 | 123 |
92 if (nargout > 0) | 124 if (nargout > 0) |
93 h = htmp; | 125 h = htmp; |
94 endif | 126 endif |
95 | 127 |
103 | 135 |
104 ## Author: Tony Richardson <arichard@stark.cc.oh.us> | 136 ## Author: Tony Richardson <arichard@stark.cc.oh.us> |
105 ## Created: July 1994 | 137 ## Created: July 1994 |
106 ## Adapted-By: jwe | 138 ## Adapted-By: jwe |
107 | 139 |
108 function h = __img__ (hax, x, y, img, varargin) | 140 function h = __img__ (hax, do_new, x, y, img, varargin) |
109 | |
110 if (isempty (img)) | |
111 error ("__img__: matrix is empty"); | |
112 endif | |
113 | 141 |
114 ## FIXME: Hack for integer formats which use zero-based indexing | 142 ## FIXME: Hack for integer formats which use zero-based indexing |
115 ## Hack favors correctness of display over size of image in memory. | 143 ## Hack favors correctness of display over size of image in memory. |
116 ## True fix will be done in C++ code. | 144 ## True fix must be done in C++ code for renderer. |
117 if (ndims (img) == 2 && (isinteger (img) || islogical (img))) | 145 if (ndims (img) == 2 && (isinteger (img) || islogical (img))) |
118 img = single (img) + 1; | 146 img = single (img) + 1; |
119 endif | 147 endif |
120 | 148 |
121 if (isempty (x)) | 149 if (! isempty (img)) |
122 x = [1, columns(img)]; | 150 |
123 endif | 151 if (isempty (x)) |
124 | 152 x = [1, columns(img)]; |
125 if (isempty (y)) | 153 endif |
126 y = [1, rows(img)]; | 154 |
127 endif | 155 if (isempty (y)) |
128 | 156 y = [1, rows(img)]; |
129 xdata = x([1, end]); | 157 endif |
130 ydata = y([1, end]); | 158 |
131 | 159 xdata = x([1, end]); |
132 if (numel (x) > 2 && numel (y) > 2) | 160 ydata = y([1, end]); |
133 ## Test data for non-linear spacing which is unsupported | 161 |
134 tol = .01; # 1% tolerance. FIXME: this value was chosen without thought. | 162 if (numel (x) > 2 && numel (y) > 2) |
135 dx = diff (x); | 163 ## Test data for non-linear spacing which is unsupported |
136 dxmean = (max (x) - min (x)) / (numel (x) - 1); | 164 tol = .01; # 1% tolerance. FIXME: this value was chosen without thought. |
137 dx = abs ((dx - dxmean) / dxmean); | 165 dx = diff (x); |
138 dy = diff (y); | 166 dxmean = (max (x) - min (x)) / (numel (x) - 1); |
139 dymean = (max (y) - min (y)) / (numel (y) - 1); | 167 dx = abs ((abs (dx) - dxmean) / dxmean); |
140 dy = abs ((dy - dymean) / dymean); | 168 dy = diff (y); |
141 if (any (dx > tol) || any (dy > tol)) | 169 dymean = (max (y) - min (y)) / (numel (y) - 1); |
142 warning ("image: non-linear X, Y data is ignored. IMG will be shown with linear mapping"); | 170 dy = abs ((abs (dy) - dymean) / dymean); |
143 endif | 171 if (any (dx > tol) || any (dy > tol)) |
144 endif | 172 warning (["image: non-linear X, Y data is ignored. " ... |
145 | 173 "IMG will be shown with linear mapping"]); |
146 htmp = __go_image__ (hax, "cdata", img, "xdata", xdata, "ydata", ydata, | 174 endif |
147 "cdatamapping", "direct", varargin {:}); | 175 endif |
148 | 176 |
149 px = __image_pixel_size__ (htmp); | 177 endif # ! isempty (img) |
150 | 178 |
151 if (xdata(2) < xdata(1)) | 179 h = __go_image__ (hax, "cdata", img, "xdata", xdata, "ydata", ydata, |
152 xdata = fliplr (xdata); | 180 "cdatamapping", "direct", varargin{:}); |
153 elseif (xdata(2) == xdata(1)) | 181 |
154 xdata = xdata(1) + [0, columns(img)-1]; | 182 if (do_new && ! ishold (hax)) |
155 endif | 183 ## Set axis properties for new images |
156 if (ydata(2) < ydata(1)) | 184 |
157 ydata = fliplr (ydata); | 185 if (! isempty (img)) |
158 elseif (ydata(2) == ydata(1)) | 186 px = __image_pixel_size__ (h); |
159 ydata = ydata(1) + [0, rows(img)-1]; | 187 |
160 endif | 188 if (xdata(2) < xdata(1)) |
161 xlim = xdata + [-px(1), px(1)]; | 189 xdata = fliplr (xdata); |
162 ylim = ydata + [-px(2), px(2)]; | 190 elseif (xdata(2) == xdata(1)) |
163 | 191 xdata = xdata(1) + [0, columns(img)-1]; |
164 ## FIXME -- how can we do this and also get the {x,y}limmode | 192 endif |
165 ## properties to remain "auto"? I suppose this adjustment should | 193 if (ydata(2) < ydata(1)) |
166 ## happen automatically in axes::update_axis_limits instead of | 194 ydata = fliplr (ydata); |
167 ## explicitly setting the values here. But then what information is | 195 elseif (ydata(2) == ydata(1)) |
168 ## available to axes::update_axis_limits to determine that the | 196 ydata = ydata(1) + [0, rows(img)-1]; |
169 ## adjustment is necessary? | 197 endif |
170 set (hax, "xlim", xlim, "ylim", ylim); | 198 xlim = xdata + [-px(1), px(1)]; |
171 | 199 ylim = ydata + [-px(2), px(2)]; |
172 if (ndims (img) == 3) | 200 |
173 if (isinteger (img)) | 201 ## FIXME -- how can we do this and also get the {x,y}limmode |
174 cls = class (img); | 202 ## properties to remain "auto"? I suppose this adjustment should |
175 mn = intmin (cls); | 203 ## happen automatically in axes::update_axis_limits instead of |
176 mx = intmax (cls); | 204 ## explicitly setting the values here. But then what information is |
177 set (hax, "clim", double ([mn, mx])); | 205 ## available to axes::update_axis_limits to determine that the |
178 endif | 206 ## adjustment is necessary? |
179 endif | 207 set (hax, "xlim", xlim, "ylim", ylim); |
180 | 208 |
181 set (hax, "view", [0, 90]); | 209 if (ndims (img) == 3) |
182 | 210 if (isinteger (img)) |
183 if (strcmp (get (hax, "nextplot"), "replace")) | 211 cls = class (img); |
184 ## Always reverse y-axis for images, unless hold is on | 212 mn = intmin (cls); |
185 set (hax, "ydir", "reverse"); | 213 mx = intmax (cls); |
186 endif | 214 set (hax, "clim", double ([mn, mx])); |
187 | 215 endif |
188 if (nargout > 0) | 216 endif |
189 h = htmp; | 217 |
190 endif | 218 endif # ! isempty (img) |
219 | |
220 set (hax, "view", [0, 90], "ydir", "reverse", "layer", "bottom"); | |
221 | |
222 endif # do_new | |
191 | 223 |
192 endfunction | 224 endfunction |
193 | 225 |
194 | 226 |
195 %!demo | 227 %!demo |
210 %! ylabel ("limits = [-5.5, 5.5]"); | 242 %! ylabel ("limits = [-5.5, 5.5]"); |
211 %! subplot (2,2,4); | 243 %! subplot (2,2,4); |
212 %! h = image (-x, -y, img); | 244 %! h = image (-x, -y, img); |
213 %! title ("image (-x, -y, img)"); | 245 %! title ("image (-x, -y, img)"); |
214 | 246 |
247 ## FIXME: Need %!tests for linear |