How to show an image with transparent background using uiimage()?

8 vues (au cours des 30 derniers jours)
Yaoyang Yeh
Yaoyang Yeh le 5 Juin 2022
Modifié(e) : DGM le 17 Nov 2023
My current code be like:
img = imread('./rocket.png');
img = imrotate(img,angle,'bilinear','crop'); % Rotation
rocket = uiimage(uif);
rocket.ImageSource = img;
rocket.Position = [x y size size];
rocket.ScaleMethod='scaleup';
But the png file has transparent background(in alpha channel), which just displayed as black background.
How can I make it transparent, just like the original image?
  1 commentaire
Image Analyst
Image Analyst le 5 Juin 2022
Modifié(e) : Image Analyst le 5 Juin 2022
What's behind it? Just the background color of the main figure that the axes is on?
Can you attach rocket.png after you read this:

Connectez-vous pour commenter.

Réponses (1)

DGM
DGM le 6 Juin 2022
Modifié(e) : DGM le 17 Nov 2023
EDIT: I just realized that you were using a uiimage() object. I'm dumb for not reading. As far as I know, uiimage() doesn't support alpha content in any consistent manner. If ImageSource is an array from the workspace, it only supports RGB images -- just RGB. Not I/IA/RGBA. If you specify the image source as a filename, it supports I/IA/RGB/RGBA, but is only compatible with a subset of what imread() is otherwise capable of reading.
I don't see that there is any workaround for using IA/RGBA images from the workspace, as your uiimage() object has no alphadata property to manipulate directly. I'm using R2019b, so maybe this behavior is less dumb in newer versions. EDIT: no, the documentation for R2022a still clearly states that only RGB inputs are supported when the source is an array, and there is no alphadata property. There may be some way to set alpha if there are underlying objects which allow it. As of R2019b, child handles are all hidden and afaik cannot be made visible due to the limited functionality of the class. Some of the handles visibility functionality has improved in other uifigure() related objects since R2019b, so that might be a possible workaround. Even if it is possible, understand that it would make your code version-dependent to do so.
For example:
% display a plain RGB image
uif = uifigure();
pep = uiimage(uif);
pep.ImageSource = 'peppers.png';
pep.Position = [0 0 512 384];
pep.ScaleMethod = 'scaleup'
% display an IA/RGBA image
rocket = uiimage(uif);
rocket.ImageSource = 'cameramanwithalpha.png'; % IA
rocket.Position = [100 50 256 256];
rocket.ScaleMethod = 'scaleup'
rocket.BackgroundColor = 'none'; % needs to be 'none'
Note that backgroundcolor needs to be set to the default value 'none', otherwise the image will not be composited with the underlying image, but with a solid color instead. The fact that this internal compositing behavior exists makes me suspect that the underlying graphics objects might not be practically manipulated even if you had access to them. That's not something I can test in R2019b or (apparently) on the forum editor.
EDIT: I recommend simply never using uiimage() to directly load images from the workspace, even though that's probably something that seems utterly necessary. Besides the RGB-only restriction, there are other undocumented problems. The RGB-only restriction implicitly also causes a restriction to uint8, uint16, and floating-point numeric classes. Logical and signed-integer images are not supported when loading from the workspace.
That's probably not the biggest concern. The reason for this RGB-only restriction turns out to be simple and ridiculous. As part of the graphics rendering routine, any images given to uiimage() this way are literally saved to disk as a low-quality JPG and then read back using the direct-file reading methods. Unless you think that this absurdity is acceptable, don't feed workspace images to uiimage() directly. The restrictions will require layers of babysitting/conversion code, and in the end, it will ruin your image and create vast drifts of temp files that won't get cleaned up until reboot. See where the discussion of compression artifacts starts in this thread.
I do offer some workaround code, but take it with a grain of salf.
Using standard image graphics objects (not uiimage()):
Depends what you want. If you want to overlay an RGBA image over other plot objects in a figure, you'll have to set the 'alphadata' property of the image graphics object to the alpha channel of your image.
[inpict,~,alpha] = imread('cameramanwithalpha.png');
basepict = imread('peppers.png');
% maybe you're displaying an image over something else
imshow(basepict); hold on
% so display the image on top of what's already there
hi = imshow(inpict); % display the image
hi.AlphaData = alpha; % set the alphadata of the object
hi.XData = [1 256] + 100; % set FG position
hi.YData = [1 256] + 50;
I can't demonstrate this directly in the forum editor, since apparently imread()'s alpha support is broken in this environment, but the above is what the image would look like. It would just be composed over whatever is beneath it in the graphics stack. If nothing else is in the axes, it's composed over the default figure background.
Alternatively, if you're just trying to view the image, and you expect it to be displayed with matting, then you have two options. You could set up some sort of in-figure composition like above. Create a checkerboard matting image, display it, and then display your transparent image on top. Personally, I think using figures as an image compositor is kind of like saving your work in Photoshop by taking a screenshot.
Using image composition outside of a figure
On the other hand, if you want to actually produce a matted image that imshow()/image()/imagesc() can handle, you can simply do the matting yourself using basic image composition. Of course, there aren't any purpose-built tools in MATLAB/IPT to do that conveniently, but MIMT does have basic tools for image composition. MIMT even has a simple tool specifically to prepare images so that they can be fed to imshow() for visualization purposes:
[inpict,~,alpha] = imread('cameramanwithalpha.png');
% combine alpha with image
inpict = joinalpha(inpict,alpha); % 256x256x2 (IA)
% compose image with a solid matting to eliminate alpha content
inpictmatted = alphasafe(inpict); % 256x256x1 (I)
imshow(inpictmatted)
Using joinalpha() and alphasafe() like this will allow imshow() to display matted representations of I/IA/RGB/RGBA/RGBAAA images.
inpict = imread('peppers.png'); % an RGB image
alpha = lingrad(imsize(inpict),[0 0; 1 1],[255 255 255; 255 255 0]); % RGB alpha
inpict = joinalpha(inpict,alpha); % 384x512x6 (RGBAAA)
inpictmatted = alphasafe(inpict); % 384x512x3 (RGB)
imshow(inpictmatted)
On the other hand, if you don't want to just visualize the image against a synthesized checkerboard matting, but instead want to compose it with some given background, then the answer might depend on the image geometries. If we're talking about images with matching geometry, you can use MIMT replacepixels() or imblend(). If their geometries are mismatched, there are various ways to deal with that. This answer might be a start. Otherwise, you might want to provide an example of your needs.
Using one of the succinct methods in the linked answer:
[FG,~,alpha] = imread('cameramanwithalpha.png');
FG = joinalpha(FG,alpha); % IA
BG = imread('peppers.png'); % RGB
offset = [50 100]; % foreground offset from NW corner [y x]
% stack the images within a working space defined by the largest image (default behavior)
% pad smaller images using a transparent black matting (default behavior)
% using 'northwest" gravity; offset is from the location implied by 'gravity'
outpict = imstacker({FG; BG},'offset',[offset; 0 0],'gravity','nw');
% merge the stack using basic src-over composition
outpict = mergedown(outpict,1,'normal');
% since the base image is opaque, we can strip the extraneous alpha channel
% if the base image were not opaque, we would want to keep it
outpict = splitalpha(outpict);
imshow(outpict)

Catégories

En savoir plus sur Convert Image Type dans Help Center et File Exchange

Produits


Version

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by