## Copyright (C) 2016 Pantxo Diribarne ## ## This program is free software; you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} impixelinfoval (@var{input1}, @var{input2}) ## ## @seealso{} ## @end deftypefn ## Author: Pantxo Diribarne ## Created: 2016-09-07 function hc = impixelinfoval (hp = [], him = []) tk = graphics_toolkit (); if (! strcmp (tk, "qt")) error ("impixelinfoval: not implemented for %s toolkit", tk) endif if (isempty (hp) || isempty (him)) print_usage (); elseif (! ishandle (hp) || ! all (ishandle (him))) error ("impixelinfoval: expect HP and HIM to be valid graphics handles") elseif (! isfigure (hp) && ! strcmp (get (hp, "type"), "uipanel")) error ("impixelinfoval: expect parent to be a figure or a uipanel") elseif (! all (strcmp (get (him, "type"), "image"))) error ("impixelinfoval: expect HIM to be an (array of) image handle(s)"); endif hf = ancestor (him(1), "figure"); update_data (hf, [], him); handle_listeners ("add", him); hc = uicontrol (hp, "style", "text", "units", "normalized", ... "position", [0 0 1 0.05], "horizontalalignment", "left", ... "deletefcn", {@hcdelete, him}); set (hf, "windowbuttonmotionfcn", {@motionfcn, hc}); endfunction function update_data (h, d, him = []) hf = ancestor (h, "figure"); if (isempty (him)) data = getappdata (hf, "__impixelinfodata__"); him = [data.him]; data = []; endif him(! ishandle (him)) = []; nim = numel (him); ## Cache image informations into the appdata of the figure for ii = 1:nim data(ii).him = him(ii); data(ii).coordfcn = get_coord_fcn (him(ii)); endfor setappdata (hf, "__impixelinfodata__", data); endfunction function handle_listeners (action, him) persistent lsn = @update_data; persistent oldhax = []; persistent hf = ancestor (him(1), "figure"); fcn = ifelse (strcmp (action, "add"), @addlistener, @dellistener); ## Figure hf = ancestor (him(1), "figure"); feval (fcn, hf, "position", lsn); ## Images him(! ishandle (him)) = []; for ii = 1:numel (him) ## Store axes oldhax = [oldhax ancestor(him(ii), "axes")]; feval (fcn, him(ii), "xdata", lsn); feval (fcn, him(ii), "ydata", lsn); feval (fcn, him(ii), "cdata", lsn); feval (fcn, him(ii), "cdatamapping", lsn); endfor oldhax = unique (oldhax(ishandle (oldhax))); for hax = oldhax feval (fcn, hax, "position", lsn); endfor endfunction function hcdelete (h, d, him) set (gcbf (), "windowbuttonmotionfcn", []); handle_listeners ("remove", him); endfunction function motionfcn (h,d, hc) hasna = 1; data = getappdata (h, "__impixelinfodata__"); pt = get (h, "currentpoint"); for ii = 1:numel (data) [str, hasnan] = data(ii).coordfcn (pt); if (! hasnan) break endif endfor set (hc, "string", str) endfunction function fcn = get_coord_fcn (him) xdata = get (him, "xdata"); ydata = get (him, "ydata"); cdata = get (him, "cdata"); if (xdata(1) > xdata(2)) cdata = fliplr (cdata); xdata = xdata(end:-1:1); endif if (ydata(1) > ydata(2)) cdata = flipud (cdata); ydata = ydata(end:-1:1); endif mapping = get (him, "cdatamapping"); hax = ancestor (him, "axes"); xl = get (hax, "xlim"); yl = get (hax, "ylim"); cmap = colormap (hax); unwind_protect units = get (hax, "units"); set (hax, "units", "pixels"); axpos = get (hax, "position"); unwind_protect_cleanup set (hax, "units", units); end_unwind_protect ## We assume "ydir" is "reverse" axpos(2) += axpos(4); axpos(4) *= -1; tmp = @(xy) (xy(:)'-axpos(1:2)) ./ axpos(3:4) .* [diff(xl) diff(yl)] + ... [xl(1) yl(1)]; pxy = __image_pixel_size__ (him); xdata(1) -= pxy(1); xdata(2) += pxy(1); ydata(1) -= pxy(2); ydata(2) += pxy(2); fcn = @(xy) pixinfo (xy, tmp, xdata, ydata, cdata, pxy, mapping, cmap); endfunction function [str, hasna] = pixinfo (xy, fig2axfcn, xd, yd, cdata, pxy,... mapping, cmap) str = ""; xy = fig2axfcn (xy); nx = columns (cdata); ny = rows (cdata); z = NA; hasna = true; if (all ((xy > [xd(1) yd(1)]) & (xy < [xd(2) yd(2)]))) hasna = false; idx(1) = sum (xy(1) > [linspace(xd(1), xd(2)-pxy(1)*2, nx)]); idx(2) = sum (xy(2) > [linspace(yd(1), yd(2)-pxy(2)*2, ny)]); z = cdata(idx(2), idx(1), :); if (ndims (cdata) == 3) ## True color str = sprintf ("(%d, %d) [%3.2f, %3.2f, %3.2f])", ... round (xy(1)), round (xy(2)), z(1), z(2), z(3)); elseif (strcmp (mapping, "direct")) ncol = rows (cmap); idx = round (z); idx(z<1) = 1; idx(z>ncol) = ncol; rgb = cmap (idx,:); if (ismember (class (cdata), {"double", "single"})) str = sprintf ("(%d, %d) %3.2f <%d> [%3.2f, %3.2f, %3.2f]",... round (xy(1)), round (xy(2)), z, idx, ... rgb(1), rgb(2), rgb(3)); else str = sprintf ("(%d, %d) <%d> [%3.2f, %3.2f, %3.2f]", round (xy(1)), round (xy(2)), z, ... rgb(1), rgb(2), rgb(3)); endif else str = sprintf ("(%d, %d) %g", round (xy(1)), round (xy(2)), z); endif endif if (isempty (str)) str = "(X, Y) Pixel Value"; endif endfunction