Overlay image on top of image

621 views (last 30 days)
Charlie Berry
Charlie Berry on 10 Aug 2018
Edited: DGM on 21 Apr 2022
Hi guys,
I currently have an image file (.png) and I would like to load this file, and then place a second image file (.png) on top of it. The second image is a signature image and is small, so I would like to put this in the bottom right hand corner of the first image.
Is there an easy way I can do this? I need the two images to remain a good quality and high resolution. I am running MATLAB 2017 and I do not have the Image Processing Toolbox.
Thanks in advance for any help / suggestions!

Answers (2)

DGM
DGM on 21 Apr 2022
Edited: DGM on 21 Apr 2022
As always, "overlay" can mean a number of things. For the purposes described, I'm assuming that this is a basic image blending/composition task, so doing figure capture is undesirable. Since the parent and inset images are not known, I'm going to use a simple example. The inset image object content is not binarized and contains soft edges. The object content is presented both as positive (bright on dark) and negative (dark on light) against black, white, and 50% gray.
First, let's start with some operations using basic MATLAB/IPT tools.
% read the two images
A = imread('peppers.png');
a = imread('insetlogo.png');
% simply insert the smaller image into the SE corner by direct indexing
sza = size(a);
B = A;
aaa = repmat(im2uint8(a),[1 1 3]); % need to cast, rescale, expand
B(end-sza(1)+1:end,end-sza(2)+1:end,:) = aaa; % insert into ROI
imshow(B)
Direct insertion is simple, but it's rarely what's intended when someone says "overlay". Often they just want to change the opacity of the image. Sometimes that works, sometimes the sparsity of the object content makes the overlay's background stick out like a sore thumb:
% simply insert the smaller image into the SE corner by scalar alpha compositing
alph = 0.5;
sza = size(a);
C = A;
aaa = repmat(im2uint8(a),[1 1 3]); % need to cast, rescale, expand
Croi = C(end-sza(1)+1:end,end-sza(2)+1:end,:); % get ROI content
C(end-sza(1)+1:end,end-sza(2)+1:end,:) = aaa*alph + Croi*(1-alph); % insert
imshow(C)
By leveraging the neutral response characteristics of simple arithmetic, we can blend the two images independent of their opacity. An addition blend works great for the white-on-black example:
% simply insert the smaller image into the SE corner by addition blending
sza = size(a);
D = A;
aaa = repmat(im2uint8(a),[1 1 3]); % need to cast, rescale, expand
Droi = D(end-sza(1)+1:end,end-sza(2)+1:end,:); % get ROI content
blended = aaa + Droi; % blend
D(end-sza(1)+1:end,end-sza(2)+1:end,:) = blended; % insert
imshow(D)
Similarly, a multiply blend works good for the black-on-white example:
% simply insert the smaller image into the SE corner by multiplication blending
sza = size(a);
E = A;
aaa = repmat(im2uint8(a),[1 1 3]); % need to cast, rescale, expand
Eroi = E(end-sza(1)+1:end,end-sza(2)+1:end,:); % get ROI content
blended = im2uint8(im2double(aaa) .* im2double(Eroi)); % blend
E(end-sza(1)+1:end,end-sza(2)+1:end,:) = blended; % insert
imshow(E)
Of course, blending can be combined with scalar alpha compositing, though it has its limitations.
% multiply blend with scalar alpha
alph = 0.5;
sza = size(a);
F = A;
aaa = repmat(im2uint8(a),[1 1 3]); % need to cast, rescale, expand
Froi = F(end-sza(1)+1:end,end-sza(2)+1:end,:); % get ROI content
blended = im2uint8(im2double(aaa) .* im2double(Froi)); % blend
F(end-sza(1)+1:end,end-sza(2)+1:end,:) = blended*alph + Froi*(1-alph); % insert
imshow(F)
Notice how this is getting progressively more complicated and how everything is going to be dependent on the class and depth of the input images? What about nonscalar alpha? What if I want to overlay a transparent PNG? What if the base image is transparent too? Nothing in base MATLAB or IPT know what to do with an RGBA image, let alone how to handle compositing two.
The answer is usually simple. Stop doing it the hard way. Not everything has to be done in MATLAB. Image manipulation software like GIMP or Photoshop exist because they're suited for their tasks. This whole affair is usually going to be simpler to accomplish outside of MATLAB.
That said, maybe you want automation or integration into a larger MATLAB workflow. There are image blending tools on the File Exchange. MIMT imblend() can do any kind of blending or composition between any two images of the same height and width. They don't need to have the same number of channels or be of the same class (so long as they're scaled correctly for their class). One or both images can have alpha content.
%% let's stop being ridiculous and just blend the image region with imblend
A = imread('peppers.png');
a = imread('insetlogo.png');
% simply insert the blended image into the SE corner by direct indexing
sza = imsize(a,2);
B = A;
Broi = B(end-sza(1)+1:end,end-sza(2)+1:end,:); % get ROI content
% imblend can do any blend at any scalar opacity, with or without an alpha channel
%blended = imblend(a,Broi,0.5,'normal'); % opacity comp only
%blended = imblend(a,Broi,1,'normal',1,'lindissolvezf',0.5); % linear dissolve comp only
%blended = imblend(a,Broi,1,'lineardodge',0.5); % addition blend at half intensity
%blended = imblend(a,Broi,1,'linearburn',0.5); % complement addition blend at half intensity
%blended = imblend(a,Broi,0.5,'screen'); % screen blend at half opacity
%blended = imblend(a,Broi,0.5,'multiply'); % multiply blend at half opacity
%blended = imblend(a,Broi,1,'linearlight'); % linearlight blend at full opacity
blended = imblend(a,Broi,1,'grainmerge',0.5); % linearlight blend at full opacity
B(end-sza(1)+1:end,end-sza(2)+1:end,:) = blended; % insert into ROI
imshow(B)
normal lindissolve
linearburn
screen multiply
linearlight grainmerge
Note again that the neutral response characteristics of basic blending alone can implicitly mask off parts of the foreground image. As before, addition (lineardodge) is neutral when FG = 0. Multiplication is neutral when the FG = 1. The complements have the opposite behavior. Symmetric modes like 'linearlight' have a neutral response when FG = 0.5, so the gray part of the image appears transparent -- all without the need for an alpha map.
If your logo is a transparent PNG, just read the image and alpha with imread(), concatenate them with cat() to form an RGBA image, and use imblend() like any other image. Use MIMT splitalpha() or basic indexing to split or discard the alpha in the resulting image. Processing IA/RGBA inputs is really no different than processing I/RGB inputs, except the need to make sure that the IA/RGBA images aren't fed into any MATLAB/IPT tools that can't handle them directly (imwrite, imshow)
%% same thing, but with an IA/RGBA logo
A = imread('peppers.png');
[a,~,aalph] = imread('insetlogotrans.png');
a = cat(3,a,aalph); % reassemble the image into IA
% simply insert the blended image into the SE corner by direct indexing
sza = imsize(a,2);
B = A;
Broi = B(end-sza(1)+1:end,end-sza(2)+1:end,:); % get ROI content
blended = imblend(a,Broi,1,'normal'); % opacity comp only
[blended,~] = splitalpha(blended); % strip alpha (it's solid in this case, so not needed)
B(end-sza(1)+1:end,end-sza(2)+1:end,:) = blended; % insert into ROI
imshow(B)
RGBA overlay
The links for MIMT and the imblend() webdocs are above. Further documentation including neutral response descriptions can be found in this PDF.
If you don't want to use imblend(), you can always open it up and figure out how to make your own code do what imblend() does.
EDIT: I'll point this out since OP mentioned it. With only a few exceptions unrelated to this topic, nothing in MIMT requires Image Processing Toolbox.
Other basic composition questions:
basic image composition (logical/multiplicative, no MIMT)
apply a soft-edged circular mask (strictly MIMT (only replacepixels() is really used))
combine masks with image in different ways (colored ROI indicators on medical diagrams/images)
instagram logo overlay (non-MIMT logical/multiplicative composition & mask feathering; MIMT imblend demo)
simple lineardodge blend
insert text into an image (basic composition with figure capture or MIMT textim())

KSSV
KSSV on 10 Aug 2018
I1 = imread('peppers.png') ;
I2 =imread('cameraman.tif') ;
image(I1)
hold on
image([300 400], [300 400],I2); % specify your locations here
  5 Comments

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!