Briandmg
Briandmg

Reputation: 57

Using editable boxes in a GUI to load part of an image in MATLAB

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: Sample picture of Mario and friends
(source: gawkerassets.com)

Upvotes: 1

Views: 91

Answers (1)

Maksim Gorkiy
Maksim Gorkiy

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

Related Questions