I have two images I need to display concurrently on screen, using the Screen('DrawTexture')
function. One image is a scene image, and second is an object, in which the background is transparent. I want to display the object on top of the scene image. However, when I try this, the object appears to have a black background.
There's definitely no problem with the object image; when called with [object,map,alpha] = imread(objectimage.png)
, the alpha value returns an appropriately-sized matrix. I have also successfully displayed these images, one on top of the other, using Python. However, due to various research reasons, this project cannot be written in Python.
I've tried looking for solutions, but the only solutions I can find relate to figures or plots, not Screen
. I suspect I need to do something with alpha blending (possibly something quite basic), but I've not been able to find any beginner-friendly guides.
My test code currently looks like this:
% screen setup
PsychDefaultSetup(2); Screen('Preference', 'SkipSyncTests', 1);
screenNum = max(Screen('Screens')); % set screen
Screen('Preference','VisualDebugLevel',3);
[w,rect] = Screen('OpenWindow',screenNum);
% Activate for alpha
Screen('BlendFunction', w, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');
% image presentation rectangles
bigImSq = [0 0 500 500];
[bigIm, xOffsetsigB, yOffsetsigB] = CenterRect(bigImSq, rect);
smImSq = [0 0 250 250];
[smallIm, xOffsetsigS, yOffsetsigS] = CenterRect(smImSq, rect);
% IMAGES
sceneIm = 'scene.png';
objIm = 'object.png';
sceneLoad = imread(sceneIm);
[objLoad,map,alpha] = imread(objIm);
% final textures for display
scene = Screen('MakeTexture',w,sceneLoad);
object = Screen('MakeTexture',w,objLoad);
% Image presentation
grey = [100 100 100];
Screen('FillRect',w,grey);
Screen('Flip',w);
WaitSecs(0.5);
Screen('FillRect',w,grey);
Screen('DrawTexture', w, scene,[],bigIm); % draw the scene
Screen('DrawTexture', w, object,[],smallIm); % draw the object
Screen('Flip',w);
WaitSecs(3);
Screen('CloseAll');
Any advice would be appreciated!
I think all you need to do is to include the alpha channel in your image during MakeTexture
.
% slightly modified boilerplate -- non-fullscreen by default,
% and set the background color (no need for all the FillRects)
PsychDefaultSetup(2);
Screen('Preference', 'SkipSyncTests', 1);
screenNum = max(Screen('Screens')); % set screen
Screen('Preference', 'VisualDebugLevel', 3);
[w, rect] = Screen('OpenWindow', screenNum, [100 100 100], [0 0 400 400]);
Screen('BlendFunction', w, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');
% image presentation rectangles
smImSq = [0 0 250 250];
[smallIm, xOffsetsigS, yOffsetsigS] = CenterRect(smImSq, rect);
Here's an image with a transparent background (for reproducibility).
% from http://pngimg.com/upload/cat_PNG100.png
[img, ~, alpha] = imread('cat.png');
size(img)
%% 2557 x 1993 x 3 (rgb)
We'll make one texture without the alpha channel, and one with.
texture1 = Screen('MakeTexture', w, img);
img(:, :, 4) = alpha;
texture2 = Screen('MakeTexture', w, img);
First, the image without the alpha channel.
Screen('DrawTexture', w, texture1, [], smallIm);
Screen('Flip', w);
Then, the RGBA texture.
Screen('DrawTexture', w, texture2, [], smallIm);
Screen('Flip', w);
sca;