Extract equivalent RGB without transparency from PNG with alpha channel

18 Ansichten (letzte 30 Tage)
I used the "imread" (https://www.mathworks.com/help/matlab/ref/imread.html#btnczv9-1-transparency) function to read a PNG image. I found that the RGB did not all approach 255 in white regions of the image. It turns out that I also needed to read the per-pixel transparency (https://www.mathworks.com/help/matlab/ref/imread.html#btnczv9-1-transparency) data from the PNG file. From a heatmap of the transparency data, I found that it was zero in the white parts, which means full transparency (https://www.w3.org/TR/PNG-DataRep.html).
[im2png,cmap,xparncy]=imread('image2.png');
hm=heatmap(xparncy,'GridVisible','off');
The fact that this shows as white means that the assumed backdrop for the image is pure white.
How do I save this image as PNG *without* alpha channel? I want the pixels where transparency/alpha was 255 as completely determined by the RGB planes. For pixels with less than 225 transparency/alpha, I want the RGB values to be modified to as to mimic the corresponding transparency, *assuming* a white background.
  2 Kommentare
Walter Roberson
Walter Roberson am 5 Jul. 2021
What about pixels with transparency between 225 and 255 ?
FM
FM am 6 Jul. 2021
I suspect that "between 255 and 255" is a typo?
255 is fully opaque, so the RGB planes completely determine the look.
Transparency < 255 assumes some mixing with the (assumed) white backdrop, and I would want the RGB values to be modified to mimic this so that the backdrop and associated transparency can be dispensed with.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Yongjian Feng
Yongjian Feng am 5 Jul. 2021
For each color channel, try
re = (1-alpha)*foreground + alpha*background.
Since here background is white, so each channel, background is just 255.
  1 Kommentar
FM
FM am 6 Jul. 2021
Thanks, Yongjian. I arrived at a relationship that is effectively the same:
% Effective pixel RGB without transparency
Peff = p + ( w - p ) ( 1 - alpha/255 )
Here, p is the per-pixel raw data [R G B] and w=[255 255 255].
I'm now off to examine Walter Roberson's code....

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Walter Roberson
Walter Roberson am 6 Jul. 2021
[im2png,cmap,xparncy]=imread('image2.png');
if ~isempty(cmap)
im2png = ind2rgb(im2png, cmap);
end
alpha = repmat(double(xparncy)/255, 1, 1, 3);
white = 255;
im_corrected = uint8(double(im2png) .* alpha + (1-alpha) .* white);
imwrite(im_corrected, 'image2_corrected.png');
  1 Kommentar
FM
FM am 6 Jul. 2021
Bearbeitet: FM am 6 Jul. 2021
Thanks, Walter! This matches what I got prompted to derive by your question about how to handle other transparency values. AFTERNOTE: Unfortunately, I can only accept one answer. Both your answer and Yongjian's answer are helpful for different reasons. I wish I can mark both as the answer.
Here is what I boiled the code down to:
[im2png,cmap,xparncy]=imread('image2.png');
% cmap is empty
% Element-by-element operations rely on automatic singleton
% extension to match array sizes
alpha = double(xparncy)/255;
% "imshow" requires "double" RGB values to span interval [0,1]
im2noX = rescale( alpha.*double(im2png) + (1-alpha)*255 );
imshow(im2noX)
% "uint8" is fine without rescaling
im2noX = uint8( alpha.*double(im2png) + (1-alpha)*255 );
imshow(im2noX)

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Lighting, Transparency, and Shading finden Sie in Help Center und File Exchange

Produkte


Version

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by