Extract equivalent RGB without transparency from PNG with alpha channel

9 ビュー (過去 30 日間)
FM
FM 2021 年 7 月 5 日
編集済み: FM 2021 年 7 月 6 日
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 件のコメント
Walter Roberson
Walter Roberson 2021 年 7 月 5 日
What about pixels with transparency between 225 and 255 ?
FM
FM 2021 年 7 月 6 日
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.

サインインしてコメントする。

採用された回答

Yongjian Feng
Yongjian Feng 2021 年 7 月 5 日
For each color channel, try
re = (1-alpha)*foreground + alpha*background.
Since here background is white, so each channel, background is just 255.
  1 件のコメント
FM
FM 2021 年 7 月 6 日
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....

サインインしてコメントする。

その他の回答 (1 件)

Walter Roberson
Walter Roberson 2021 年 7 月 6 日
[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 件のコメント
FM
FM 2021 年 7 月 6 日
編集済み: FM 2021 年 7 月 6 日
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)

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeLighting, Transparency, and Shading についてさらに検索

製品


リリース

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by