Simultaneously display image on two monitors

My laptop is connected to two external monitors. I would like an image to appear on each monitor at exactly the same time. When I use this script, the image appears on the monitor for axHandle1 slightly before axHandle2:
figHandle=figure('WindowState', 'fullscreen','MenuBar', 'none', 'ToolBar', 'none','OuterPosition',[4000 0 2560 1440],'color','w');
axHandle1 = axes('Units','normalized','Position',[0 0 1 1],'color','w');
figHandle=figure('WindowState', 'fullscreen','MenuBar', 'none', 'ToolBar', 'none','OuterPosition',[1440 0 2560 1440],'color','w');
axHandle2 = axes('Units','normalized','Position',[0 0 1 1],'color','w');
imshow(rgb1,'Parent',axHandle1);
imshow(rgb2,'Parent',axHandle2);

Answers (1)

Stephen23
Stephen23 on 24 Feb 2019
Edited: Stephen23 on 6 Mar 2019
Try:
imh(1) = imshow(...., 'Visible','off');
imh(2) = imshow(...., 'Visible','off');
then later:
set(imh, 'Visible','on')
EDIT: Create the figures (or uipanels) with their Visible property set to 'off':
fgh(1) = figure(...., 'Visible','off');
fgh(2) = figure(...., 'Visible','off');
axh(2) = axes(..., 'Parent',fgh(2));
axh(1) = axes(..., 'Parent',fgh(1));
imh(2) = imshow(..., 'Parent',axh(2));
imh(1) = imshow(..., 'Parent',axh(1));
Then, when you want them to both appear simultaneously:
set(fgh, 'Visible','on')

12 Comments

Unfortunately, that did not work. I used this code but it seems that "visible" is not an option with imshow:
imh(1) = imshow(rgb1,'Parent',axHandle1, 'Visible','off');
This is the error:
Error using images.internal.imageDisplayParsePVPairs>parseParamValuePairs (line 154)
Expected input number 4, PARAM, to match one of these values:
'Colormap', 'DisplayRange', 'InitialMagnification', 'XData', 'YData', 'Parent', 'Border',
'Reduce'
The input, 'Visible', did not match any of the valid values.
Error in images.internal.imageDisplayParsePVPairs (line 133)
[common_args,specific_args] =
parseParamValuePairs(varargin(param1_index:end),valid_params,...
Error in images.internal.imageDisplayParseInputs (line 69)
[common_args,specific_args] = images.internal.imageDisplayParsePVPairs(varargin{:});
Error in imshow (line 245)
images.internal.imageDisplayParseInputs({'Parent','Border','Reduce'},preparsed_varargin{:});
Stephen23
Stephen23 on 25 Feb 2019
Edited: Stephen23 on 25 Feb 2019
@Jessica Yorzinski: that is a bit strange and unfortunate, as Visible is clearly listed as a property of the image object:
See my edited answer for another approach using figures. If you want the figures to be visible the entire time, then you can easily do the same thing with uipanel.
Thanks for taking another look. This is better but still not quite what I need it to do. I used the below code, as suggested. However, when the image appears (the "visible on" line), a figure bar briefly appears and says "Figure," then the "Figure" text disappears, but the figure bar remains on the screen. Any other ideas to make this work?
figHandle=figure('WindowState', 'fullscreen','MenuBar', 'none', 'ToolBar', 'none','OuterPosition',[1440 0 2560 1440],'color','w');
axHandle2 = axes('Units','normalized','Position',[0 0 1 1],'color','w');
axis off
I=imread(FaceStimuli_01a);
fgh(2)=figure('WindowState', 'fullscreen','MenuBar', 'none', 'ToolBar', 'none','OuterPosition',[1440 0 2560 1440],'color','w','Visible','off');
axh(2) = axes('Units','normalized','Position',[0 0 1 1],'color','w','Parent',fgh(2));
axis off
imh(2) = imshow(rgb1, 'Parent',axh(2));
set(fgh(2), 'Visible','on')
Stephen23
Stephen23 on 26 Feb 2019
Edited: Stephen23 on 26 Feb 2019
@Jessica Yorzinski: your code does not use text anywhere. I have no idea what "text" you mean.
Probably you should use uipanel and adjust their visibility.
When a figure is created, there is a bar that appears on the top of the screen and it says "Figure." It seems to be a default property of creating a figure. How do you suggest using uipanel instead?
Stephen23
Stephen23 on 26 Feb 2019
Edited: Stephen23 on 26 Feb 2019
'When a figure is created, there is a bar that appears on the top of the screen and it says "Figure."'
As far as I can tell you are describing the figure title itself. You can see it when the figure is visible, and you can't see it when the figure is not visible. You can change it by setting the Name property.
"How do you suggest using uipanel instead?"
It is really much the same, just with the extra step of adding uipanels:
  1. create figures: visible=on.
  2. add uipanels to figures: visible=off.
  3. add axes to uipanels
  4. add images to axes.
  5. when you a want to, set the uipanels to visible=on.
Why is this useful? Because you can create the uipanels with visible=off and you can add any axes or other child objects that you want to them: any child objects will also be invisible if the parent uipanel is also invisible. Then you only need to change the uipanel to visible=on and all of its child objects will be visible too (assuming that they already have visible=on). Read the uipanel help to know more.
Unfortunately, I don't think this will quite work. This is what I need to happen:
(1) White screen (completely blank, no figure bars, etc.) displayed on monitor 1 and monitor 2
(2) After specific time, image appears on monitor 1 and image appears on monitor 2 at the exact same time.
(3) After specific time, white screen displayed on monitor 1 and monitor 2 at exact same time
(4) After specific time, image appears on monitor 1 and image appears on monitor 2 at the exact same time.
.
.
.
"Unfortunately, I don't think this will quite work."
1. Create two figures with:
  • positions equal to your screen sizes (you will find the the graphcis root MonitorPositions property useful).
  • set them to have a white background.
2. Add uipanels (visible=off, no title, no border)
3. Add any images to the uipanels
4. Change the uipanels to visible=on when required.
Read the documentation, experiment, and you will actually make some progress. I don't see any reasons why that should not work (I have done many similar GUIs myself, using the visibilty property to show different objects depending on some variable, uicontrol, or timer object).
Thanks for your continued help. I pasted in some code below but the image actually never becomes visible and this is only for one monitor. I'm not sure how to (1) get the image to appear when visible is set to 'on' and (2) how to exapnd this to two monitors and have the uipanel visible turn on for both monitors at the exact same time (it seems that these uipanels still runs into the same problem of one monitor showing the image slightly before the other monitor).
%Create a white screen
figHandle=figure('WindowState', 'fullscreen','MenuBar', 'none', 'ToolBar', 'none','OuterPosition',[1440 0 2560 1440],'color','w');
axHandle1 = axes('Units','normalized','Position',[0 0 1 1],'color','w');
axis off
%Add uipanel
hp=uipanel('BackgroundColor','white','Position',[0 0 1 1],'Visible','off');
axHandle2=axes(hp);
%Load image
imshow(rgb1, 'Parent',axHandle2);
%Show image
hp=uipanel('Visible','on');
(1) You need to add the axes to the uipanel, as I stated in my last comment. You added the axes to the figure, which means the uipanel is totally useless.
(2) Use the graphics root MonitorPositions property as I mentioned in my last comment, and use each row to set the position of one figure. I did not mention using the property fullscreen.
Something like this:
fgh(2) = figure(....);
uih(2) = uipanel(fgh(2), 'Visible','off',...);
axh(2) = axes(uih(2),...); % OR axes(..., 'Parent',uih(2))
imh(2) = imshow(..., 'Parent',axh(2));
Thanks for these additional suggestions. I was able to get the code to work (see below). However, this code still has the same issue as my original code. When the last line comes into play--set(hp, 'Visible','on')-- an image appears on one screen and then (with a brief delay) the other. They do not appear simultaneously. Any other thoughts?
ScreenSize=get(0,'MonitorPositions');
SecondScreen=ScreenSize(3,:);
ThirdScreen=ScreenSize(2,:);
figHandle(1)=figure('WindowState', 'fullscreen','MenuBar', 'none', 'ToolBar', 'none','OuterPosition',[4000 0 2560 1440],'color','w');
axHandle1 = axes('Units','normalized','Position',[0 0 1 1],'color','w');
axis off
figHandle(2)=figure('WindowState', 'fullscreen','MenuBar', 'none', 'ToolBar', 'none','OuterPosition',[1440 0 2560 1440],'color','w');
axHandle2 = axes('Units','normalized','Position',[0 0 1 1],'color','w');
axis off
I=imread(FaceStimuli_01);rgb1 = flipdim(I,1);
I2=imread(FaceStimuli_02);rgb2 = flipdim(I2,1);
hp(1)=uipanel(figHandle(1), 'BackgroundColor','white','Position',[0 0 1 1],'Visible','off'); axh(1) = axes('Parent',hp(1));
hp(2)=uipanel(figHandle(2),'BackgroundColor','white','Position',[0 0 1 1],'Visible','off'); axh(2) = axes('Parent',hp(2));
imshow(rgb1,'Parent',axh(1));
imshow(rgb2,'Parent',axh(2));
set(hp, 'Visible','on')
I have no idea if you can do anything better than what Stephan suggested, but you have to bear in mind that what you want may not be achievable as you only control the first link of a fairly long chain. To get an image displayed, it goes through:
  • matlab
  • the java virtual machine
  • the OS
  • the graphics card
  • the monitor panels
Any of these can introduce a jitter over which you have no control.

Sign in to comment.

Categories

Find more on Environment and Settings in Help Center and File Exchange

Products

Release

R2018b

Tags

Asked:

on 24 Feb 2019

Commented:

on 8 Mar 2019

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!