- Undocumented Matlab - https://undocumentedmatlab.com -

Transparency in uicontrols

Posted By Yair Altman On December 10, 2014 | 5 Comments

I would like to welcome back guest blogger Robert Cumming, an independent UK contractor who developed a commercial class-based Matlab GUI framework [1]. Today, Robert will highlight how he customized the use of uicontrol CData property.
Before detailing how I used this feature I will start with a basic example. A number of times (see example1 [2], example2 [3]), users have asked is it possible to set the background of uicontrols to be transparent?
There are a number of reasons why we might want to do this. For example, we might wish to display a clickable image, and don’t want its background (which is typically white) to be displayed. To place on image on a uicontrol we use its CData property, which according to the official Matlab documentation [4] must be a 3-D array of truecolor RGB values.
Let’s start with a simple example:

uicontrol with white bgcolor
uicontrol with white bgcolor

f = figure;
img = imread('Matlab_Logo.png');
s = size(img);
pb = uicontrol('Style','pushbutton', 'Position',[10 10 s(2) s(1)], 'CData',img, ...
               'Callback',@(a,b)disp('push button'), 'BackgroundColor','green');

The code above produces the figure on the right; when we click on the image, the pushbutton callback is executed.
However the background of the button is white. This is because the image is MxNx3 rectangle the size of the button.
We can set the white portion of the image to be transparent so that it will show the background color of the pushbutton (in our example, ‘green’).
First, we read the image and convert it to a 2D double array that ranges from 0 to 1 (the original image was RGB uint8, 0 to 255). Then find the index for each RGB where the value is 1 (white):

img = imread('Matlab_Logo.png');
img = double(img)/255;
index1 = img(:,:,1) == 1;
index2 = img(:,:,2) == 1;
index3 = img(:,:,3) == 1;

uicontrol with transparent bgcolor
uicontrol with transparent bgcolor

The color (in this example) that we want to make transparent is where all RGB is 1, so calculate a logical index where this is true and update the img variable:

indexWhite = index1+index2+index3==3;
for idx = 1 : 3
   rgb = img(:,:,idx);     % extract part of the image
   rgb(indexWhite) = NaN;  % set the white portion of the image to NaN
   img(:,:,idx) = rgb;     % substitute the update values
end
set(pb, 'CData', img)     % Update the CData variable

Updating the CData we get the image with the green background. We could set the Color of the figure to be green, to match the uicontrol’s background color:

set(f, 'Color', get(pb,'BackgroundColor'))

Transparent background

As mentioned here [2], we can link the CData to a screenshot image of the parent figure.
When we combine the two methods above, we get the effect of the uicontrol background being transparent (the smaller logo is a button that can be clicked):

uicontrol with transparent background (optical illusion)
uicontrol with transparent background (optical illusion)

f = figure(); % create a figure with an axes on it
ax = axes('Units','pixels', 'Position',[0 0 560 420], 'XTick',[], 'YTick',[], ...
          'Nextplot','add', 'YDir','reverse');
% read the big logo image - background of the figure
bigImage = imread('Matlab_LogoBig.png');
image(bigImage, 'parent', ax);  % Display the image in the axes
% read a smaller image - background of button
img = imread('Matlab_Logo.png');
s = size(img);
pos = [10 10 s(2) s(1)];  %Position of the button
% Extract the portion of the image where the button will be.
F = getframe(ax,pos);  % take a screenshot of the parent figure
pb = uicontrol('Style','pushbutton', 'Units','pixels', 'Position',pos, ...
               'Callback',@(a,b)disp('push button'));
% as before - calculate where the button image is white.
img = double(img)/255;
index1 = img(:,:,1) == 1;
index2 = img(:,:,2) == 1;
index3 = img(:,:,3) == 1;
indexWhite = index1+index2+index3==3;
% for each pixel, replace the white portion with the parent image data
for idx = 1 : 3
   rgb = 1-img(:,:,idx);                   % To make the picture quirky change the RGB
   pImage = double(F.cdata(:,:,idx))/255;  % extract part of the image
   rgb(indexWhite) = pImage(indexWhite);   % set the white portion of the image to the parent
   img(:,:,idx) = rgb;                     % substitute the update values
end
% Update the push button image
set(pb, 'CData', img)

Customizing checkboxes

I have shown how to manipulate the CData of a button. Unfortunately, not all uicontrols have a CData property — the documentation states that pushbuttons and toggle buttons are the only uicontrols that are fully supported. It also mentions that you can use it in radiobuttons and checkboxes, which brings me to how I used it in my application: I use this feature on a checkbox – to use it properly we need to ensure that the size of the image we put in CData is 16x16x3. In this case we set a transparent color by setting pixel RGB values to NaN:

uicontrol with transparent bgcolor
uicontrol with transparent bgcolor

f = figure('Color','red');
smiley = imread('smiley.png');
smiley = double(smiley)/255;
index1 = smiley(:,:,1) == 1;
index2 = smiley(:,:,2) == 1;
index3 = smiley(:,:,3) == 1;
indexWhite = index1+index2+index3==3;
% Create a first smiley which has the white background.
uicontrol('Style','checkbox', 'Position',[25 50 16, 16], 'CData',smiley, ...
          'Callback',@(a,b)disp('-1 smiley'));
% For each pixel, replace the white portion with the parent image data
for idx = 1 : 3
   rgb = smiley(:,:,idx);  % To make the picture quirky change the RGB
   rgb(indexWhite) = NaN;
   smiley(:,:,idx) = rgb;  % substitute the update values.
end
% Create a second smiley which has the transparent background.
uicontrol('Style','checkbox', 'Position',[25 25 16, 16], 'CData',smiley, ...
          'Callback',@(a,b)disp('+1 smiley'), 'BackgroundColor','red');

The upper smiley is the original image; the lower smiley has its white pixels set to NaN, and the background colors of the control and the figure set to equal. The checkbox has no text is displayed, the user just clicks on the smiley to invoke the callback.
Note: This trick works in R2014b but I have deliberately used old style set and get commands for compatibility with older versions of Matlab. I have used this in all versions from R2008a onwards, and I suspect it probably works in older versions as well.
I used this feature several times in my Matlab GUI Toolbox. One of the uses was to create a pin for locking a dynamic panel in position: The panel is by default hidden; when the user hovers the mouse near the edge, the dynamic panel appears after some predefined time (2 seconds). A checkbox with a manipulated CData masquerades as a pin for locking the panel in position. When the panel is pinned, the CData changes accordingly:

transparent uicontrol usage example
transparent uicontrol usage example

Conclusions

1. The CData property of a uicontrol can be set to NaN to imitate transparent behavior.
2. By linking this with the parent CData we can super-impose an image on top of another image.
3. We can customize other uicontrols using the method to turn checkboxes (for example) into clickable images.
Have you used this feature? If so please share in a comment below.
Editor’s note: I have shown another alternative for displaying clickable transparent images in my article on displaying animated/transparent GIFs [5]. Readers might also find interest in the related article on transparent uipanels [6]. Next week I plan to show how MathWorkers Ben Tordoff and David Sampson coerced a simple checkbox uicontrol to have a radically different appearance, as flex-panel dividers in their GUI Layout Toolbox, similarly to what Robert explained today. Stay tuned!  – Yair

Categories: Guest bloggers, GUI, Low risk of breaking in future versions, Undocumented feature


5 Comments (Open | Close)

5 Comments To "Transparency in uicontrols"

#1 Comment By Sergio On March 26, 2016 @ 14:51

It was a very well way to learn customize uicontrols.

But I have a doubt. Is posible that a “CDATA image” can be placed in a left or right position of uicontrol object, not in the center position of uicontrol ?

Thank you.

Att: A Engineer.

#2 Comment By Yair Altman On March 26, 2016 @ 19:51

@Sergio – see [13]

More details can be found in Chapter 6 of my [14].

#3 Comment By Jeff On April 25, 2016 @ 10:59

Hello Yair,
I have used your exact code found in section “Transparent Background”, but the generated figure does not render the same as your example. There are vertical striations in the transparent button image. (Please see [15]).
[16]
I’m wondering if it is a software version issue. I’m running R2015b. Any ideas/solutions to repair this issue?
Thank you.

#4 Comment By Yair Altman On April 25, 2016 @ 11:14

@Jeff – try changing your figure’s Renderer property value to 'OpenGL' – painters/zbuffer do not support transparency ( [17]).

#5 Comment By edouard On June 4, 2016 @ 01:05

Hello Yair! your codes are great!!! I used the transparent background one. It helped me a lot.

I would add as a NB that the position “pos” used by the getframe function is set in the coordinate system of the axes graph, meaning the position of the child image and the position used in the getframe function should be seperated. Otherwise the getframe function take the background from another part of the image.

I just have one question. When I superimpose the child image on the parent somewhere away from the edges I get a thin line colored by the ‘BackgroundColor’ on the left edge of the child image, meaning everything I want to be transparent is transparent except for that thin line. Do you have any idea what that could be due to? It seems to be something to do with the ‘Extent’ but I can’t figure it out..

Thanks


Article printed from Undocumented Matlab: https://undocumentedmatlab.com

URL to article: https://undocumentedmatlab.com/articles/transparency-in-uicontrols

URLs in this post:

[1] Matlab GUI framework: https://sites.google.com/site/matpihome/matlab-gui-framework

[2] example1: http://www.mathworks.com/matlabcentral/answers/7928-matlab-gui-set-transparent-background-color-for-components

[3] example2: https://www.mathworks.com/matlabcentral/newsreader/view_thread/169067

[4] official Matlab documentation: http://www.mathworks.com/help/matlab/ref/uicontrol-properties.html

[5] displaying animated/transparent GIFs: http://undocumentedmatlab.com/blog/displaying-animated-gifs

[6] transparent uipanels: http://undocumentedmatlab.com/blog/transparent-uipanels

[7] Images in Matlab uicontrols & labels : https://undocumentedmatlab.com/articles/images-in-matlab-uicontrols-and-labels

[8] Panel-level uicontrols : https://undocumentedmatlab.com/articles/panel-level-uicontrols

[9] Icon images & text in Matlab uicontrols : https://undocumentedmatlab.com/articles/icon-images-in-matlab-uicontrols

[10] Plot markers transparency and color gradient : https://undocumentedmatlab.com/articles/plot-markers-transparency-and-color-gradient

[11] Plot line transparency and color gradient : https://undocumentedmatlab.com/articles/plot-line-transparency-and-color-gradient

[12] Displaying animated GIFs : https://undocumentedmatlab.com/articles/displaying-animated-gifs

[13] : https://undocumentedmatlab.com/blog/button-customization

[14] : https://undocumentedmatlab.com/books/matlab-java

[15] : https://www.dropbox.com/s/ry9bu7sxk5zy0hx/matlab_transparency.JPG?dl=0

[16] : https://undocumentedmatlab.com/images/matlab_transparency.jpg

[17] : http://uk.mathworks.com/help/releases/R2012a/techdoc/creating_plots/f3-84337.html?refresh=true#f3-102410

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.