Blurry figures when concatenating images

4 views (last 30 days)
I have a lot of figures saved as jpg that I am trying to merge together into subplots. Here is an example of the way my code is formatted:
% Load saved figures
a=imread('filename1.jpg');
b=imread('filename2.jpg');
%prepare subplots
figure
subplot(1,2,1),imshow(a);
subplot(1,2,2),imshow(b);
%merge
concat_img=[a;b];
print(gcf,'-dtiff','newfilename');
close all
When I run this, it loads the images correctly into a grid, but they are all extremely blurry and you can't actually see the figures.

Accepted Answer

DGM
DGM on 22 Oct 2023
Edited: DGM on 23 Oct 2023
First, don't save line plots as JPG. It's unnecessarily destructive and it usually results in a bigger file for literally no benefit.
Unless you need to combine raster image content with plots or other graphics objects, don't use figures as a general image compositor. You will have no practical control over how the images are resized, and they will be subject to nearest-neighbor display interpolation by default, so thin line features will be easily destroyed. At this point you're literally taking a screenshot, resizing it blindly, and taking a screenshot of the screenshot. It gets worse every time. Don't save images by displaying them and taking screenshots of the figure. Save images directly using imwrite().
If you want to concatenate images of the same size, you can just concatenate them as you would any other array. You already know that, because you did concatenate them. You just didn't do anything with the concatenated image.
concat_img=[a;b];
If they aren't of the same size, you can use padarray() or imresize() to resize them. If you want something that's more convenient, you can use imtile() to tile the images with whatever padding you want.
Compare the two examples:
We start by ruining our plot by saving it as a trash-quality 70% 4:2:0 JPG. Sample:
Then we blindly resize the images and take a screenshot of a bunch of resized screenshots.
% a captured figure as JPG
inpict = imread('untitled.jpg');
% make it worse by making it smaller with nearest-neighbor interpolation
% and then save it again by taking a screenshot
for k = 1:4
subplot(2,2,k)
imagesc(inpict)
axis off
end
% saved image size is not determined by the original raster images
% the output size is determined by the displayed size
% due to display interpolation, fine details are completely lost
saveas(gcf,'trash2.jpg')
Alternatively, we start by saving our plot as a clean, lightweight, lossless PNG. Sample:
Then we just combine the images into another image and then save the image like one would save an image.
% a captured figure as PNG
inpict = imread('untitled.png');
% join the images using imtile()
% i'm using a bold border color so it's obvious what's happening
outpict = imtile({inpict inpict inpict inpict},'gridsize',[2 2], ...
'bordersize',[10 10],'backgroundcolor',[0.5 0.3 0.8]);
% save the image as an image
imwrite(outpict,'composite.png')
Click on either of the output images to view them at full size.
Unreadable JPG composition:
  • Image size: 970x1177 (resolution is not preserved, content is completely lost)
  • Filesize: 78kB (file takes up more space)
Lossless PNG composition:
  • Image size: 1282x1546 (resolution and content are preserved)
  • Filesize: 65kB (file is actually smaller)

More Answers (0)

Categories

Find more on Images in Help Center and File Exchange

Products


Release

R2020a

Community Treasure Hunt

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

Start Hunting!