Reputation: 57
I have a displayable image which I load via uigetfile. I want to allow the user to choose which portion of the image he wants to load by keying in the pixel coordinates of the top-left pixel and the bottom-right pixel into editable boxes. The problem is that I'm having some serious issues with the handles structure used to store data and don't quite understand how to use it.
Here is my code. I can easily load the 4 pixels in the topleft corner of the image (that's the default setting), but I fail to load anything else when the editable box values are changed. Is there something I'm missing here?
function mygui
%%
%Initialise GUI and set up editable boxes and push buttons
f = figure('Visible', 'off', 'Position', [360 500 450 285]);
handles.data.topleft1 = 1; %x-axis position of topleft pixel
handles.data.topleft2 = 1; %y-axis position of topleft pixel
handles.data.botright1 = 2; %x-axis position of bottom right pixel
handles.data.botright2 = 2; %y-axis position of bottom right pixel
hloader = uicontrol('Style', 'pushbutton', 'String', 'Load File', 'Position', [8 5 50 20], 'Callback', {@loadbutton_Callback, handles});
htopleft1 = uicontrol('Style', 'edit', 'String', handles.data.topleft1, 'Position', [25 40 15 10], 'Callback', {@topleft1_Callback, handles});
htopleft2 = uicontrol('Style', 'edit', 'String', handles.data.topleft2, 'Position', [40 40 15 10], 'Callback', {@topleft2_Callback, handles});
hbotright1 = uicontrol('Style', 'edit', 'String', handles.data.botright1, 'Position', [25 30 15 10], 'Callback', {@botright1_Callback, handles});
hbotright2 = uicontrol('Style', 'edit', 'String', handles.data.botright2, 'Position', [40 30 15 10], 'Callback', {@botright2_Callback, handles});
set([f, hloader, htopleft1, htopleft2, hbotright1, hbotright2], 'Units', 'normalized');
movegui(f, 'center')
set(f, 'Visible', 'on', 'toolbar', 'figure');
%%
%Loader pushbutton
function loadbutton_Callback(source, eventdata, handles)
[filename, pathname, filterindex] = uigetfile('*.jpg'); %Choose mario picture here from the directory you downloaded it from
picture = imread(strcat(pathname,filename));
topleft1 = handles.data.topleft1;
topleft2 = handles.data.topleft2;
botright1 = handles.data.botright1;
botright2 = handles.data.botright2;
picture = picture([topleft1:botright1], [topleft2:botright2], :); %Trim picture dimensions according to editable box inputs
imagesc(picture)
end
%%
%Editable boxes
function topleft1_Callback(source, eventdata, handles)
%Get new input from editable box; Save it into guidata handles structure thingy
topleft1 = str2double(get(source, 'String'));
handles.data.topleft1 = topleft1;
guidata(source, handles)
end
%(Repeat 3 more times for topleft2, botright1 and botright2)
end
And as usual, here's the picture which I'm trying to trim:
(source: gawkerassets.com)
Upvotes: 1
Views: 91
Reputation: 240
I can suggest a solution with some changes that might be not as efficient, bu they'll work. I would do this kind of passing data between callbacks simply using the fact that Your whole GUI is a nested function, so all the callbacks can acces handles
without even running the guidata
function:
Do achieve this just change the way boxes are calling their callbacks from
(... 'Callback', {@topleft1_Callback, handles})
to:
(... 'Callback', @topleft1_Callback)
Now adjust arguments taken by Your callbacks, so the don't take three but two:
function myCallback(source,eventdata)
although none of those will be used, so You could simply write:
function myCallback(~,~) as You MATlab will probably suggest. And You don't need the
guidata(source, handles);
line in any of Your callbacks anymore, since handles
can be accesed anyway just by its name.
Upvotes: 1