Extract equivalent RGB without transparency from PNG with alpha channel

조회 수: 14(최근 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
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일
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)

댓글을 달려면 로그인하십시오.

제품


릴리스

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by