MATLAB.Exponenta
–Û·Ë͇ Matlab&Toolboxes

Приложения с GUI и дескрипторная графика

Управление просмотром изображений: изменение масштаба, полосы прокрутки

В этом разделе мы рассмотрим создание приложения ImageView с графическим интерфейсом пользователя, которое будет содержать оси, вертикальную и горизонтальную полосы прокрутки, кнопки для увеличения и уменьшения масштаба просмотра ZoomIn и ZoomOut и кнопку Open для открытия графического файла.

Кроме этого, будет приведен пример использования функции zoom, входящей в MATLAB, для интерактивного изменения масштаба изображения при помощи мыши.

Описание графического интерфейса

Работа в нашем приложении ImageView выглядит следующим образом. Сначала кнопки ZoomIn и ZoomOut недоступны. Нажатие на кнопку Open выводит стандартное диалоговое окно открытия файла. После открытия графического файла его содержимое выводится на оси и кнопка ZoomIn становится доступной. Масштаб просмотра можно увеличить, причем после увеличения масштаба становятся доступными две полосы прокрутки, расположенные внизу и справа от осей, и кнопка ZoomOut. Пользуясь полосами прокрутки, можно перемещаться по изображению. При уменьшении масштаба просмотра изображения кнопкой ZoomOut до исходного полосы прокрутки пропадают и кнопка ZoomOut становится недоступной.

Используемые функции и основные свойства объектов

Для вывода стандартного диалогового окна открытия файла (для выбора графического файла) мы применим функцию uigetfile, которая возвращает имя и путь к выбранному файлу.

Функция uigetfile, как и другие функции MATLAB для создания стандартных диалоговых окон описаны в разделе Справка по функциям для создания диалоговых окон.

Для считывания изображения мы обратимся к функции imread, которая для большинства цветных изображений возвращает трехмерный массив. Первые два размера этого массива совпадают, соответственно, с высотой и шириной изображения, а третье измерение содержит цвет в формате RGB (отличие может быть для графических файлов в формате tiff). Для черно-белых изображений функция imread возвращает двумерный массив, каждый элемент которого содержит информацию об оттенке серого цвета соответствующего пикселя.

Для вывода изображения на оси мы используем функцию imshow, которая подбирает пропорции осей в зависимости от размера изображения. Во входном аргументе imshow задается массив, возвращаемый функцией imread.

Графическое окно и оси создаются при помощи функций figure и axes, во входных аргументах этих функций задаются пары с названиями свойств и их значениями:

figure('НазваниеСвойства', значение, 'НазваниеСвойства', значение,…)
axes('НазваниеСвойства', значение, 'НазваниеСвойства', значение,…)

Свойства осей и графических окон описаны в следующих разделах

Полосы прокрутки и кнопки создаются при помощи функции uicontrol, входные аргументы которой указываются парами:

uicontrol('НазваниеСвойства', значение, 'НазваниеСвойства', значение,…)

Тип создаваемого объекта определяется значением свойства Style. В нашем приложении будут кнопки и полосы прокрутки, им соответствуют значения 'pushbutton' и 'slider'.

При создании каждого из объектов мы будем указывать его положение. За положение объекта отвечает его свойство Position, значением которого является вектор из четырех элементов

[x   y   width   height]

где (x, y) - координаты левого нижнего угла объекта, width - его ширина, а height, соответственно, высота.

При задании положения и размеров важно

  1. указать единицы измерения, для чего необходимо установить свойству Units объекта подходящее значение, мы будем использовать значение 'pixels' и задавать размеры и положение в пикселях;
  2. понимать, что размеры и положение графического окна задаются относительно монитора, размеры и положение осей, кнопок и полос прокрутки задаются относительно графического окна, причем координаты нижнего левого угла монитора (в пикселях) равны (1, 1) и координаты нижнего левого угла графического окна (в пикселях) равны (1, 1).

Для полос прокрутки важную роль играют свойства Min, Max, Value и SliderStep. Значение Value зависит от положения бегунка полосы прокрутки и изменяется от заданных свойствами Min и Max значений. Значением свойства SliderStep является вектор из двух элементов, каждый из которых может принимать значения от 0 до 1. Относительное перемещение бегунка при щелчке по правой или левой кнопкам со стрелкой (на краях полосы прокрутки) определяется значением первого элемента вектора. То, на сколько переместится бегунок при щелчке слева или справа от него по полосе прокрутки, определяется значением второго элемента.

При программировании приложения с графическим интерфейсом пользователя полезно задавать объектам уникальные имена (теги), которые можно использовать для обращения к объекту и его свойствам (см. следующий раздел).

Обработка событий элементов управления, структура программы, обмен данными между подфункциями

При нажатии пользователем кнопки в запущенном приложении, или при продвижении бегунка по полосе прокрутки возникает событие Callback данных объектов. При этом для выполнения в программе соответствующих действий следует

  1. запрограммировать функцию обработки данного события;
  2. с событием Callback объекта связать соответствующую функцию.

Наше приложение ImageView будет состоять из основной функции ImageView с подфункциями обработки событий элементов интерфейса, содержащимися в файле ImageView.m. В основной функции ImageView создаются следующие объекты: графическое окно, оси, три кнопки Open, ZoomIn и ZoomOut, а так же вертикальная и горизонтальная полосы прокрутки. При создании кнопок и полос прокрутки мы будем задавать в качестве значения свойства Callback этих объектов указатель на соответствующую подфункцию обработки события и задавать тег объектов:

function ImageView
 ...	
uicontrol('НазваниеСвойства', значение, ...,  'Tag', 'btnOpen', 'Callback',@btnOpen_Callback);
 ...

После основной функции в файле ImageView мы запрограммируем подфункции обработки событий кнопок и полос прокрутки, например для обработки события Callback кнопки Open:

function btnOpen(src, evt)
% операторы функции обработки события Callback кнопки Open.

Входных аргументов у функций обработки событий в нашем примере будет всегда два. Первый входной аргумент src подфункции обработки события Callback содержит указатель на объект, событие Callback которого обрабатывается в данный момент времени (второй входной аргумент в случае кнопок и полос прокрутки не используется, но он нужен по соглашению, принятому в MATLAB при программировании обработки событий).

При обработке события Callback одного из элементов управления, например кнопки ZoomIn, нам понадобится изменять значения свойств других объектов (полос прокрутки и пределов осей) для обеспечения их согласованной работы. Для получения и изменения свойств объекта необходимо знать указатель на объект, сами значения изменяются при помощи функции set. Например, для задания пределов [2 20] для оси x достаточно написать

set(УказательНаОси, 'XLim', [2 20])

Для получения значения свойства объекта используется функция get. Например, для получения значения бегунка на полосе прокрутки достаточно написать

val = get(УказательНаПолосуПрокрутки, 'Value')

Более подробно про указатели на объекты, а также про функции set и get написано в следующих разделах:

  • Текущий графический объект; указатели на объекты http://matlab.exponenta.ru/forum/gui/book1/index.php#3
  • Доступ к значениям свойств графических объектов http://matlab.exponenta.ru/forum/gui/book1/index.php#4

Итак, в подфункции обработки события одного из элементов управления необходимо иметь доступ к указателям на другие элементы. Например, при перемещении бегунка полосы прокрутки нам придется менять пределы осей, следовательно при обработке события Callback полосы прокрутки нужен указатель на оси. Переменные функций являются локальными, т.е. они видны только в пределах функции. Следовательно, нужен механизм, позволяющий получить из функции обработки события доступ к указателям на нужные объекты приложения.

Для получения указателей на объекты графического окна мы будем вызывать функцию guihandles, в качестве входного аргумента которой задается указатель на любой объект графического окна, а выходным ее аргументом является структура (краткие сведения о работе со структурами в MATLAB приведены здесь http://matlab.exponenta.ru/forum/gui/book2/5_structure.php). Названия полей этой структуры совпадают с тегами объектов, данными объектам при их создании, поля содержат указатели на соответствующие объекты графического окна.

Например, если при создании осей мы задали им тег axMain, то в функции btnZoomIn_Callback обработки события Callback кнопки ZoomIn достаточно написать

function btnZoomIn_Callback (src, evt)
% src - указатель на кнопку
h = guihandles(src);
...

Теперь в h.axMain (т.е. в поле axMain структуры h) содержится указатель на оси. Для задания пределов по оси x, например [2 20], следует использовать функцию set и свойство осей XLim:

set(h.axMain, 'XLim', [2 20])

Для получения указателя на оси мы будем использовать также функцию gca (gca возвращает текущие оси).

Следующая проблема, связанная с тем, что переменные функции являются локальными - обмен данными между функциями обработки событий (в приложении ImageView понадобится знать размеры рисунка в функциях обработки событий). Для обмена данными мы используем структуру данных приложения, которую назовем data. При появлении нового параметра в некоторой функции, который должен быть доступен из других функций обработки событий, мы занесем его значение в некоторое поле структуры, например для параметра ImW это будет поле ImW:

ImSize = size(A);
data.ImW = ImSize(2);

Для того, чтобы сохранить структуру данных приложения, следует в этой же функции обработки события вызвать guidata

guidata(src, data)

Здесь в качестве первого входного аргумента функции guidata задается указатель src на любой объект графического окна, а вторым аргументом является имя сохраняемой структуры.

Для получения значения параметра в другой функции следует сначала получить структуру data при помощи той же самой функции guidata, но уже вызванной с одним входным и выходным аргументами (входной аргумент src - указатель на любой объект графического окна, выходной аргумент - структура данных приложения):

data = guidata(src)

Теперь для доступа к ImW в функции обработки события достаточно обратиться к полю ImW структуры data, т.е. написать data.ImW.

При попытке считывания из файла при помощи функции imread может возникнуть ошибка (если файл не является графическим). Для обработки исключительной ситуации мы будем использовать конструкцию try...catch

try
   % блок операторов, выполнение которых может привести к ошибке
catch
  % операторы, выполняющиеся при возникновении ошибки в первом блоке
end

Увеличение и уменьшение изображения, продвижение по изображению

Запрограммируем кнопку ZoomIn так, чтобы после k нажатий на нее масштаб увеличивался в 2k + 1 раз, т.е. после первого нажатия масштаб увеличивается в 3 раза по сравнению с исходным, после второго - в пять раз и т.д., причем центр изображения остается в центре осей (см. рисунок ниже, где оси обозначены красной рамкой).Запрограммируем кнопку ZoomIn так, чтобы после нажатий на нее масштаб увеличивался в раз, т.е. после первого нажатия масштаб увеличивается в 3 раза по сравнению с исходным, после второго - в пять раз и т.д., причем центр изображения остается в центре осей (см. рисунок ниже, где оси обозначены красной рамкой).

После первого нажатия на кнопку ZoomIn появляются вертикальная и горизонтальная полосы прокрутки и кнопка ZoomOut становится доступной. В качестве значения Value вертикальной (горизонтальной) полосы прокрутки, определяющего положение бегунка, мы будем задавать ординату (абсциссу) середины текущей области рисунка, отображаемой на осях. Например, для горизонтальной полосы прокрутки это будет

XLim(1) + DeltaX / 2;

где

DeltaX = XLim(2) - XLim(1) + 1;

Тогда, если в качестве значений свойств Min и Max для полос прокрутки задать, соответственно, следующие значения:

1 + DeltaX / 2     и     ImW - DeltaX / 2 + 1

где ImW - ширина рисунка, то перемещение бегунка полосы прокрутки из одного крайнего положения в другое даст возможность пролистать все изображение по горизонтали.

Для удобства пользования полосой прокрутки мы сделаем так, чтобы щелчок слева или справа от бегунка переводил изображение на следующее значение влево или вправо (это относительное перемещение в долях единицы):

StepX = DeltaX / (ImW - DeltaX)

А при щелчке по левой и правой кнопкам со стрелкой на полосе прокрутки выберем относительное перемещение в 10 раз меньше, т.е.

0.1*StepX

Аналогичные действия будем выполнять и при обработки события Callback вертикальной полосы прокрутки.

Нажатие на кнопку ZoomOut должно приводить к уменьшению изображения во столько же раз, во сколько оно увеличивается при нажатии на кнопку ZoomIn.

При выводе изображения на оси учтем, что функция imshow изменяет размеры осей, делая их пропорциональными выводимому на них изображению. Следовательно, как только размеры изображения известны, следует изменить положение и размеры полос прокрутки так, чтобы при увеличении изображения (т.е., когда полосы прокрутки становятся видимыми) они располагались бы рядом с осями (без зазоров).

Функция ImageShow с подфункциями

В этом разделе приведена основная функция ImageShow с подфункциями обработки событий элементов интерфейса. В основной функции ImageShow создаются следующие объекты: графическое окно, оси, кнопки Open, ZoomIn, ZoomOut и горизонтальная и вертикальная полосы прокрутки. Теги и функции обработки событий Callback элементов интерфейса приложения ImageShow собраны в следующей таблице.

Объект Тег Подфункция обработки события Callback
графическое окно не задаем нет такого события
оси axMain нет такого события
кнопка Open btnOpen btnOpen_Callback
кнопка ZoomIn btnZoomIn btnZoomIn_Callback
кнопка ZoomOut btnZoomOut btnZoomOut_Callback
горизонтальная полоса прокрутки sldHor sldHor_Callback
вертикальная полоса прокрутки sldVert sldVert_Callback
function ImageView
% основная функция 

% создание графического окна
figure('MenuBar','none','NumberTitle','off','Name','Image View',...
    'Units','pixels','Position',[200 200 250 320],'Resize','off');

% создание кнопки Open... 
% и связывание с ее событием Callback функции btnOpen_Callback
uicontrol('Style','pushbutton','String','Open...','Units','pixels',...
    'Position',[10 10 50 20],...
    'Tag','btnOpen','Callback',@btnOpen_Callback);

% создание кнопки ZoomIn 
% и связывание с ее событием Callback функции btnZoomIn_Callback
uicontrol('Style','pushbutton','String','ZoomIn','Units','pixels',...
    'Position',[90 10 60 20],'Enable','off',...
    'Tag','btnZoomIn','Callback',@btnZoomIn_Callback);

% создание кнопки ZoomOut 
% и связывание с ее событием Callback функции btnZoomOut_Callback
uicontrol('Style','pushbutton','String','Zoom Out','Units','pixels',...
    'Position',[160 10 60 20],'Enable','off',...
    'Tag','btnZoomOut','Callback',@btnZoomOut_Callback);

% создание осей
axes('Units','pixels','Position',[20 100 200 200],'XTick',[],'YTick',[],'Box','on',...   
    'Tag','axMain');

% создание вертикальной полосы прокрутки 
% и связывание с ее событием Callback функции sldVert_Callback
uicontrol('Style','slider','Units','pixels',...
    'Position',[220 100 10 200],...
    'Tag','sldVert','Callback',@sldVert_Callback,'Visible','off');

% создание горизонтальной полосы прокрутки 
% и связывание с ее событием Callback функции sldHor_Callback
uicontrol('Style','slider','Units','pixels',...
    'Position',[20 90 200 10],...
    'Tag','sldHor','Callback',@sldHor_Callback,'Visible','off');

function btnOpen_Callback (src, evt)
% функция обработки события Callback кнопки Open

% получаем структуру указателей на объекты приложения
h = guihandles(src);
% вызываем стандартное диалоговое окно открытия файла
[filename, pathname] = uigetfile('*.*', 'Open file');
% проверяем, был ли выбран файл
if ~isequal(filename,0)
   % файл был выбран, считываем изображение и выводим на оси с обработкой 
   % исключительных ситуаций
    try
        % считываем изображение в матрицу A
        A  = imread(strcat(pathname,filename));   
        % узнаем размеры изображения и записываем их в поля ImW и ImH структуры data
        ImSize = size(A);
        data.ImW = ImSize(2);
        data.ImH = ImSize(1);     
        % выводим изображение на оси
        imshow(A)
        % функция imshow изменяет тег осей, поэтому задаем его снова
        set(gca, 'Tag','axMain')
        
        % устанавливаем размеры и положение полос прокрутки в зависимости 
        % от размеров и положения осей, полученных после вывода изображения
        % сначала получаем размеры осей  
        axPos = get(h.axMain,'Position');
        % затем задаем размеры и полос прокрутки в зависимости 
        % от соотношения ширины и высоты изображения
        if data.ImW > data.ImH          
            sldLength = axPos(4) * data.ImH / data.ImW;
            sldY = axPos(2) + axPos(4) / 2 -sldLength /2;
            set(h.sldVert,'Position',[axPos(1)+axPos(3) sldY 10 sldLength]);
            set(h.sldHor,'Position',[axPos(1) sldY-10 axPos(3) 10]);            
        else
            sldLength = axPos(3) * data.ImW / data.ImH;
            sldX = axPos(1) + axPos(3) / 2 -sldLength /2;
            set(h.sldHor,'Position',[sldX axPos(2)-10 sldLength 10]);
            set(h.sldVert,'Position',[sldX + sldLength  axPos(2) 10 axPos(4) ]);
        end
        
        % устанавливаем текущее увеличение равное 1 (нет увеличения)
        data.magnif=1;       
        % сохраняем структуру данных приложения 
        guidata(src,data)
        % делаем полосы прокрутки невидимыми
        set([h.sldHor,  h.sldVert], 'Visible', 'off')
        set(h.btnZoomIn,'Enable','on')
    catch
    end 
end

function btnZoomIn_Callback (src, evt)
% функция обработки события Callback кнопки ZoomIn

% получаем структуру указателей на объекты приложения
h = guihandles(src);
% делаем доступной кнопку ZoomOut
set(h.btnZoomOut,'Enable','on')
% получаем структуру данных приложения
data = guidata(src);
% увеличиваем на единицу коэффициент масштаба просмотра
data.magnif = data.magnif+1;
% сохраняем структуру данных приложения
guidata(src, data)

% изменяем пределы осей по y

% получаем текущие пределы осей
YLim = get(h.axMain,'YLim');
% вычисляем середину по вертикали
Ycenter = (YLim(2)+YLim(1))*0.5;
% вычисляем, на сколько надо увеличить изображение по вертикали
DeltaY = data.ImH / (2^(data.magnif-1)+1);
% устанавливаем новые пределы осей по y
Ymin = max([1, Ycenter - 0.5*DeltaY]);
Ymax = min([data.ImH, Ymin + DeltaY]);
set(h.axMain,'YLim',[Ymin Ymax])

% изменяем пределы по x

% получаем текущие пределы осей
XLim = get(h.axMain,'XLim');
% вычисляем середину по горизонтали
Xcenter = (XLim(2)+XLim(1))*0.5;
% вычисляем, на сколько надо увеличить изображение по горизонтали
DeltaX = data.ImW /  (2^(data.magnif-1)+1);
% устанавливаем новые пределы осей по x
Xmin = max([1, Xcenter - 0.5*DeltaX]);
Xmax = min([data.ImW, Xmin + DeltaX]);
set(h.axMain,'XLim',[Xmin Xmax])

% задаем шаг вертикальной полосы прокрутки

% получаем пределы вертикальной оси
YLim = get(h.axMain,'YLim')
% вычисляем соответствующий шаг бегунка
DeltaY = YLim(2) - YLim(1) + 1;
StepY = DeltaY/(data.ImH-DeltaY);
% устанавливаем предельные и текущее значения вертикальной полосы прокрутки 
% и величины изменения значения  при щелчке по полосе прокрутки 
% и по ее кнопкам со стрелкой 
set(h.sldVert,'Min',1+DeltaY/2,'Max',data.ImH-DeltaY/2+1,...
    'SliderStep',[0.1*StepY StepY],'Value',YLim(1)+DeltaY/2,...
    'Visible','on')

% задаем шаг горизонтальной  полосы прокрутки

% получаем пределы горизонтальной оси
XLim = get(h.axMain,'XLim');
DeltaX = XLim(2) - XLim(1) + 1;
% вычисляем соответствующий шаг бегунка
StepX = DeltaX/(data.ImW-DeltaX);
% устанавливаем предельные и текущее значения горизонтальной полосы прокрутки 
% и величины изменения значения  при щелчке по полосе прокрутки 
% и по ее кнопкам со стрелкой 
set(h.sldHor,'Min',1+DeltaX/2,'Max',data.ImW-DeltaX/2+1,...
    'SliderStep',[0.1*StepX StepX],'Value',XLim(1)+DeltaX/2,...
    'Visible','on')


function btnZoomOut_Callback (src, evt)
% функция обработки события Callback кнопки ZoomOut

% получаем структуру указателей на объекты приложения
h = guihandles(src);
% получаем структуру данных приложения
data = guidata(src);
% проверяем, увеличено ли изображение
if data.magnif > 1
      % уменьшаем коэффициент увеличения
     data.magnif = data.magnif-1;
      if data.magnif == 1
         % если коэффициент увеличения равен 1, то изображение не должно быть увеличенным
         % делаем невидимыми полосы прокрутки
         set([h.sldVert, h.sldHor],'Visible','off')
         % делаем недоступной кнопку ZoomOut
         set(h.btnZoomOut,'Enable','off')
         % устанавливаем исходные пределы осей
         set(h.axMain,'XLim',[1 data.ImW])
         set(h.axMain,'YLim',[1 data.ImH])

      else    % коэффициент увеличения больше 1

          % вычисляем пределы оси y
          YLim = get(h.axMain,'YLim');
          Ycenter = (YLim(2)+YLim(1))*0.5;
          DeltaY = data.ImH /  (2^(data.magnif-1)+1);
          Ymin = max([1, Ycenter - 0.5*DeltaY]);
          Ymax = min([data.ImH, Ymin + DeltaY]);
          Ymin = Ymax - DeltaY;
          Ymin =max([1, Ymax - DeltaY]);
          YLim = [Ymin Ymax];

          % вычисляем пределы оси x
          XLim = get(h.axMain,'XLim');
          Xcenter = (XLim(2)+XLim(1))*0.5;
          DeltaX = data.ImW /  (2^(data.magnif-1)+1);
          Xmin = max([1, Xcenter - 0.5*DeltaX]);
          Xmax = min([data.ImW, Xmin + DeltaX]);
          Xmin =max([1, Xmax - DeltaX]);
          XLim = [Xmin Xmax];

          % устанавливаем пределы осей
          set(h.axMain,'XLim',XLim)
          set(h.axMain,'YLim',YLim)

          % вычисляем соответствующий шаг бегунка вертикальной оси
          DeltaY = YLim(2) - YLim(1) + 1;
          StepY = DeltaY/(data.ImH-DeltaY);
          % устанавливаем предельные и текущее значения вертикальной полосы прокрутки 
          % и величины изменения значения  при щелчке по полосе прокрутки 
          % и по ее кнопкам со стрелкой 
          set(h.sldVert,'Min',1+DeltaY/2,'Max',data.ImH-DeltaY/2+1,...
            'SliderStep',[0.1*StepY StepY],'Value',YLim(1)+DeltaY/2,...
            'Visible','on')
          % вычисляем соответствующий шаг бегунка горизонтальной оси
          DeltaX = XLim(2) - XLim(1) + 1;  
          StepX = DeltaX/(data.ImW-DeltaX);          
          % устанавливаем предельные и текущее значения горизонтальной полосы прокрутки 
          % и величины изменения значения  при щелчке по полосе прокрутки 
          % и по ее кнопкам со стрелкой 
          set(h.sldHor,'Min',1+DeltaX/2,'Max',data.ImW-DeltaX/2+1,...
            'SliderStep',[0.1*StepX StepX],'Value',XLim(1)+DeltaX/2,...
            'Visible','on')
    end
    % сохраняем структуру данных приложения
    guidata(src,data)
end

function sldVert_Callback (src, evt)
% функция обработки события Callback вертикальной полосы прокрутки

% получаем структуру указателей на объекты приложения
h = guihandles(src);
% получаем структуру данных приложения
data = guidata(src);
% получаем пределы оси y
YLim = get(h.axMain,'YLim');
% вычисляем смещение изображения по вертикали
DeltaY = YLim(2) - YLim(1) + 1;
% получаем текущее значение бегунка вертикальной полосы прокрутки
SliderPos = get(src,'Value')
% вычисляем соответствующие пределы оси y
Ymax = min([data.ImH, SliderPos + DeltaY/2]);
Ymin = Ymax - DeltaY + 1;
% задаем пределы оси y
set(h.axMain,'YLim',[Ymin Ymax])

function sldHor_Callback (src, evt)
% функция обработки события Callback горизонтальной полосы прокрутки

% получаем структуру указателей на объекты приложения
h = guihandles(src);
% получаем структуру данных приложения
data = guidata(src);
% получаем пределы оси x
XLim = get(h.axMain,'XLim');
% вычисляем смещение изображения по горизонтали

DeltaX = XLim(2) - XLim(1) + 1;
% получаем текущее значение бегунка горизонтальной полосы прокрутки
SliderPos = get(src,'Value');
% вычисляем соответствующие пределы оси x
Xmax = min([data.ImW, SliderPos + DeltaX/2]);
Xmin = Xmax - DeltaX + 1;
% задаем пределы оси x
set(h.axMain,'XLim',[Xmin Xmax])

Использование функции zoom для изменения масштаба просмотра

Для интерактивного изменения масштаба просмотра при помощи мыши может быть использована стандартная команда zoom. Команда zoom вызывается с параметрами, имеющими следующий смысл.

zoom on - включение режима интерактивного масштабирования на осях текущего графического окна. После выполнения этой команды курсор мыши, наведенный на оси, приобретает форму лупы.
Щелчок левой кнопкой мыши по осям приводит к увеличению масштаба просмотра в два раза, причем точка, в которой был сделан щелчок, остается неподвижной. Кроме того, при помощи мыши можно выделить прямоугольную область, которая должна остаться на осях.
Щелчок левой кнопкой мыши по осям с одновременным удержанием клавиши Alt приводит к уменьшению масштаба просмотра в два раза.
Щелчок правой кнопкой по осям приводит к появлению контекстного меню, в котором можно выбрать уменьшение масштаба просмотра или возврат к исходному масштабу.
Двойной щелчок левой кнопкой мыши по осям возвращает исходный масштаб осей.

zoom off - выключение режима интерактивного масштабирования на осях текущего графического окна.

zoom out - возврат к исходному масштабу осей.

zoom reset -текущий масштаб становится исходным, к которому возвращает zoom out.

zoom - переключение между zoom on и zoom off.

zoom xon - включение режима zoom on только для оси x

zoom yon - включение режима zoom on только для оси y

Кроме этого, команда zoom может быть вызвана в функциональной форме:

zoom(f) - увеличение масштаба в f раз (если f от 0 до 1, то уменьшение).

zoom(fig, option) - все вышеописанные режимы: on, off, out, reset, xon и yon применяются к графическому окну, указатель на который записан во входной аргумент fig. Входной аргумент option должен содержать один из вышеописанных параметров, заключенный в апострофы, например: zoom(fig, 'on').

В качестве примера приведем приложение ZoomInOut, в котором нажатие на кнопку Zoom включает интерактивный режим изменения масштаба изображения.

Приложение ZoomInOut содержит основную функцию ZoomInOut, в которой создаются следующие объекты: графическое окно, оси, кнопка Оpen и кнопка Zoom, и подфункцию btnOpen_Callback обработки события Callback кнопки Open.

В подфункции btnOpen_Callback происходит вывод стандартного диалогового окна открытия файла. Далее, если файл был выбран, то изображение читается функцией imread и выводится на оси функцией imshow с обработкой исключительных ситуаций (т.к. выбранный файл может и не быть графическим).

Для обработки события Callback кнопки Zoom не требуется специальной функции, вместо этого команда zoom on указана в качестве значения (строкового) свойства Callback кнопки Zoom.

function ZoomInOut
% основная функция приложения

% создание графического окна
figure('MenuBar','none','NumberTitle','off','Name','ZoomInOut',...
    'Units','pixels','Position',[200 200 250 320],'Resize','off');

% создание кнопки Open и связывание с ее событием Callback функции btnOpen_Callback
uicontrol('Style','pushbutton','String','Open...','Units','pixels',...
    'Position',[10 10 50 20],...
    'Tag','btnOpen','Callback',@btnOpen_Callback);

% создание кнопки Zoom и связывание с ее событием Callback команды zoom on
uicontrol('Style','pushbutton','String','Zoom','Units','pixels',...
    'Position',[90 10 60 20],...
    'Tag','btnZoomIn','Callback','zoom on');

% создание осей
axes('Units','pixels','Position',[20 100 200 200],'XTick',[],'YTick',[],'Box','on',...   
    'Tag','axMain');


function btnOpen_Callback(src, evt)
% функция обработки события Callback кнопки Open

% вызываем стандартное диалоговое окно открытия файла
[filename, pathname] = uigetfile('*.*', 'Open file');
% проверяем, был ли выбран файл
if ~isequal(filename,0)
   % файл был выбран, считываем изображение и выводим на оси с обработкой 
   % исключительных ситуаций
    try
        % считываем изображение в матрицу A
        A  = imread(strcat(pathname,filename));   
        % выводим изображение на оси
        imshow(A)
    catch
    end 
end


Поиск по сайту:

Система Orphus

Яндекс.Метрика