Images in Matlab uicontrols & labels

A couple of weeks ago, a reader here asked how to integrate images in Matlab labels. I see quite a few queries about this, so I wanted to take today’s opportunity to explain how this can be done, and how to avoid common pitfalls.

In fact, there are two main methods of displaying images in Matlab GUI – the documented method, and the undocumented one:

The documented method

Some Matlab uicontrols (buttons, radio and checkboxes) have the CData property that can be used to load and display an image. For example:

imgData = imread('myImage.jpg');   % or: imread(URL)
hButton = uicontrol('CData',imgData, ...);

While label uicontrols (uicontrol(‘style’,’text’, …)) also have the CData property, it has no effect on these controls. Instead, we can create an invisible axes that displays the image using the image function.

The undocumented method

web-based images

I’ve already written extensively about Matlab’s built-in support for HTML in many of its controls. The supported HTML subset includes the <img> tag, and can therefore display images. For example:

htmlStr = '<html><b>Logo</b>: <img src="https://undocumentedmatlab.com/images/logo_68x60.png"/></html>';
hButton = uicontrol('Position',[10,10,120,70], 'String',htmlStr, 'Background','white');

uicontrol with HTML image

uicontrol with HTML image

local images

Note that the image src (filename) needs to be formatted in a URL-compliant format such as 'http://www.website.com/folder/image.gif' or 'file:/c:/folder/subfolder/img.png'. If we try to use a non-URL-format filename, the image will not be rendered, only a placeholder box:

uicontrol('Position',..., 'String','<html><img src="img.gif"/></html>');  %bad
uicontrol('Style','list', ... 'String',{...,'<html><img src="img.gif"/></html>'});  %bad

Ill-specified HTML images in Matlab uicontrols Ill-specified HTML images in Matlab uicontrols

Ill-specified HTML images in Matlab uicontrols

Instead, we need to use correct URI syntax when specifying local images, which means using the 'file:/' protocol prefix and the '/' folder separator:

>> iconsFolder = fullfile(matlabroot,'/toolbox/matlab/icons/');
>> iconUrl = strrep(['file:/' iconsFolder 'matlabicon.gif'],'\','/');
>> str = ['<html><img src="' iconUrl '"/></html>']
str =
<html><img src="file:/C:/Program Files/MATLAB/ ..... /icons/matlabicon.gif"/></html>
 
>> uicontrol('Position',..., 'String',str);
>> uicontrol('Style','list', ... str});

Correctly-specified HTML images in Matlab uicontrols Correctly-specified HTML images in Matlab uicontrols

Correctly-specified HTML images in Matlab uicontrols

A similar pitfall exists when trying to integrate images in GUI control tooltips. I already discussed this issue here.

You can use HTML to resize the images, using the <img> tag’s width, height attributes. However, beware that enlarging an image might introduce pixelization effects. I discussed image resizing here – that article was in the context of menu-item icons, but the discussion of image resizing also applies in this case.

images in text labels

As for text labels, since text-style uicontrols do not unfortunately support HTML, we can use the equivalent Java JLabels, as I have explained here. Here too, we need to use the 'file:/' protocol prefix and the '/' folder separator if we want to use local files rather than internet files (http://…).

Java customizations

Using a uicontrol’s underlying Java component, we can customize the displayed image icon even further. For example, we can specify a different icon for selected/unselected/disabled/hovered/pressed/normal button states, as I have explained here. In fact, we can even specify a unique icon that will be used for the mouse cursor when it hovers on the control:

Custom cursor Custom cursor

Custom uicontrol cursors

Categories: GUI, Icons, Low risk of breaking in future versions, Stock Matlab function, Undocumented feature

Tags: , , , , ,

Bookmark and SharePrint Print

28 Responses to Images in Matlab uicontrols & labels

  1. Morteza says:

    Hi Dear Yair
    That was nice point…
    Thanks so much for your help.

  2. Peter Gardman says:

    Dear Yair,
    First, sorry, my petition is not related to this entry, but I didn’t know where to post it.
    I use error(‘…’) when I want to stop execution of a running m-file and show an error message. However, together with the error message, Matlab displays on screen all the other info with the line number or the mfile name where the error occurred (“Error in ==>..”). This distracts from the error message, and the end-user doesn’t care about all this info. I only want to display a message and stop execution. For example:

    if x < 0
       error('x should not be negative')
    end

    with pcoded files the extra info is not shown, but, in a non-compiled mfile, how to make "error(…)" not display all the extra info? Any suggestions are very welcome. Thank you very much.

  3. stetsc says:

    Hi there Yair,

    thanks for this very usefull post. But I have an ongoing question for this topic:

    Is it possible to align text and image vertically centered?

    Because in my Buttons, the text is aligned strictly at the bottom of the image. It would look more “professional” when I could align the text centered to the image.

    • Yair Altman says:

      @Stetsc – yes, we can do this using the underlying Java component:

      jButton = findjobj(hButton);
      jButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);  % or: set(jButton,'HorizontalTextPosition',javax.swing.SwingConstants.CENTER);
      jButton.setVerticalTextPosition(javax.swing.SwingConstants.CENTER);    % or: set(jButton,'VerticalTextPosition',javax.swing.SwingConstants.CENTER);

      This way, we can separately set the text and image locations in many different manners (left/center/right, top/center/bottom). I explain all these options in detail in section 6.1 of my Matlab-Java programming book.

    • stetsc says:

      Hi Yair,

      thanks for the quick answer. I tried out, what you told me, but I can’t see any changes in the alignment of the text and image on the Button.

      Here is my code:

      htmlButtonStr_aSi = ['<b>Beschreibung der gewählten Messgröße</b>: '];
      DH.info_aSi = uicontrol(DH.var,'Style','PushButton',...       
                       'Parent',frame_lists,...
                       'Units','normalized', ...
                       'position',v.pos76,...
                       'TooltipString','',...
                       'FontUnits','normalized', ...    
                       'fontsize',0.225,...      
                       'fontweight','normal',...      
                       'String',htmlButtonStr_aSi,...
                       'HorizontalAlignment','left', ...
                       'Enable','on', ...
                       'Callback','msgbox(char(DH.desc((get(DH.aSi,''Value'')))),''Info enthaltene Messgröße'')');
      jButton_info_aSi = findjobj(DH.info_aSi);    %find Java-Handle of Button
      set(jButton_info_aSi,'HorizontalTextPosition',javax.swing.SwingConstants.LEFT);
      set(jButton_info_aSi,'VerticalTextPosition',javax.swing.SwingConstants.CENTER);

      I’m using MATLAB R2009b. Where is my fault?
      Greetings,
      stetsc

    • Yair Altman says:
      set(jButton_info_aSi,'HorizontalTextPosition',javax.swing.SwingConstants.CENTER);

      not:

      set(jButton_info_aSi,'HorizontalTextPosition',javax.swing.SwingConstants.LEFT);

      Also, to use HTML formatting as you are obviously trying to do, you need to add “<html>” to the beginning of your string:

      htmlButtonStr_aSi = ['<html><b>Beschreibung der gewählten Messgröße</b>: </html>'];
    • stetsc says:

      Oh, I just saw, that your comment-system interprets the HTML-Tags in my first codeline. And with this, you cannot see what I really coded. So I try it this way:

      htmlButtonStr_aSi = ['<html><b>Beschreibung der gewählten Messgröße</b>:<img src="file:\' img_path_info '"/>;</html>'];

      As you can see, I build the string out of the descriptive string “Beschreibung der gewählten Messgröße:” and the variable “img_path_info”.

      So why it does not work?

    • stetsc says:

      I have to mention, that the Text and the image appear on the Button, side by side, as I want them to be, but the vertical positions are not really centered. The text is to low and the image to high.

      Thanks for your help.

    • Yair Altman says:

      HTML has its own way of aligning the items, just as on a webpage. If you want to have more control then you need to set the image not via HTML but using the uicontrol’s CData property, and then you can control the placement of them separately as I have shown above.

    • stetsc says:

      Ah! I understand. Yair, you are my man!

      Now it looks like I want it to. Many thanks for your help.

      Here is the final code for all those who have the same problem out there:

      info_icon_path = fullfile(pwd, '\resource\graph\info_icon_transparent.png');
      DH.info_aSi = uicontrol(DH.var,'Style','PushButton',...       
                       'Parent',frame_lists,...
                       'Units','normalized', ...
                       'position',v.pos76,...
                       'TooltipString','',...
                       'FontUnits','normalized', ...    
                       'fontsize',0.45,...      
                       'fontweight','bold',...      
                       'String','Description',...
                       'HorizontalAlignment','left', ...
                       'Enable','on', ...
                       'Callback','msgbox(''It works!'')');
      jButton_info_nFS = findjobj(DH.info_nFS);                                           %find Java-Handle of Button
      set(jButton_info_nFS,'HorizontalTextPosition',javax.swing.SwingConstants.RIGHT);    %align text
      set(jButton_info_nFS,'VerticalTextPosition',javax.swing.SwingConstants.CENTER);     %align text

      And now the button has the image on the left, followed by the descriptive text. Both are vertically centered.

      So again, thanks to you, Yair.

      Greetings,
      stetsc

    • stetsc says:

      I forgot one codeline:

      jButton_info_nFS.setIcon(javax.swing.ImageIcon(info_icon_path));    %add image to button

      Just needs to be added to the previous posted code.
      Sorry :-)

      stetsc

    • instead of using setIcon you could simply use the CData property:

      imgData = imread(info_icon_path);
      uicontrol(... , 'CData',imgData);
  4. Emanuel R says:

    Hi!
    How can I save the cdata as a gif? I want to use the Icons outside Matlab.
    Thx!

  5. Asaf B says:

    Hi Yair,

    is it possible to display HTML text on axes ?

    %it is not work  
    h_table = axes('HandleVisibility','callback', 'position',[ 0 0  1 1 ]);
    htmlStr = '<b>Logo</b>:';
    h_DataText = text (0.5,0.5 ,htmlStr,'clipping','on','parent',h_table);
  6. Klaus says:

    Dear Yair,

    thank you for the detailed description. Do you see a chance to put a 90 deg rotated text on a uicontrol (pushbutton)?

    Best regars

    Klaus

    • @Klaus – not directly, but you can create a small image and add it to the button’s CData. As long as you don’t resize the button too much in either direction, this should work nicely.

  7. Ronit says:

    Do you know a way to show images on push buttons via GUIDE?
    Thanks in advance!

  8. Sneha says:

    Hi Yair
    I added image to my push button using the CData property but was not able to set its position.
    The image added by me is positioned at the center of the button by default. Is there any way to change its position to bottom of the push button

    • @Sneha – either enlarge your image by adding empty space at the top, or use Java by accessing the button’s underlying Java control and then calling setVerticalAlignment(javax.swing.SwingConstants.BOTTOM).

    • Sneha says:

      Hi Yair,
      Tried enlarging my image and added empty space on top of the image and this worked. Thank you for the help. I wanted to align my text and tried using the following lines

      jButton = findobj(hObject);
      jButton.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
      but got an error stating:
      No appropriate method, property, or field 'setVerticalAlignment' for class 'matlab.ui.control.UIControl'.
       
      Error in MSCT&gt;pushbutton2_CreateFcn (line 812)
      jButton.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
       
      Error in gui_mainfcn (line 95)
              feval(varargin{:});
       
      Error in MSCT (line 44)
          gui_mainfcn(gui_State, varargin{:});
       
      Error in
      matlab.graphics.internal.figfile.FigFile/read&gt;@(hObject,eventdata)MSCT('pushbutton2_CreateFcn',hObject,eventdata,guidata(hObject))

      Can you please help me with this.

    • You need to use findjobj, not findobj. Read the post (and the other articles on this blog) carefully.

    • Sneha says:

      Hi, I am using MATLAB 2016 version

Leave a Reply

Your email address will not be published. Required fields are marked *