如何制作彩色幻影坦克?How to generate an ARGB Mirage Tank?

22 views (last 30 days)
网上的教程都是黑白的,还要用到PS。我想幻影坦克不就是利用了Alpha通道么?用MATLAB应该也能做吧?求大佬指教!
A Mirage Tank is a specially made PNG image that show different colors above different backgrounds, thanks to its Alpha channel. There's a format that combines two images into one single image, which shows image No.1 above white background, while shows image No.2 above black background.
Surprisingly I wasn't able to find MATLAB codes generating such image?

Accepted Answer

埃博拉酱
埃博拉酱 on 17 Dec 2019
Edited: 埃博拉酱 on 17 Dec 2019
自己解决了这个问题,分享一波~
function varargout = MirageTankV2(Image1,Image2,varargin)
%输入两张图,制作幻影坦克!
%Image1和Image2三个维度视为列、行、G/AG/RGB/ARGB三个维度,uint8类型。
%默认情况下,白色背景显示Image1,黑色背景显示Image2。
%可选设置Background1和Background2,必须为uint8标量,表示背景的灰度。
%% 可选参数
Background1=255;
Background2=0;
for a=1:2:length(varargin)
switch varargin{a}
case "Background1"
Background1=varargin{a+1};
case "Background2"
Background2=varargin{a+1};
end
end
%% 尺寸统一化
Background1=double(Background1);
Background2=double(Background2);
[Alpha1,Image1]=ChannelSplit(double(Image1));
[Alpha2,Image2]=ChannelSplit(double(Image2));
[Image1,Image2]=ArrayAdapt(Image1,Image2,"SizeOneCopy",true);
[Alpha1,Alpha2]=ArrayAdapt(Alpha1,Alpha2);
BackgroundDelta=Background1-Background2;
Color=Alpha1.*(Background1-Image1)-Alpha2.*(Background2-Image2);
if BackgroundDelta==0
warning("提供了两个相同的背景,将输出不透明图像");
Alpha=[];
else
Alpha=Color./BackgroundDelta;
end
Color=(Alpha1.*Background2.*(Background1-Image1)+Background1.*Alpha2.*(Image2-Background2))./Color;
Color=uint8(Color*255/max(Color,[],"all"));
Alpha=mean(Alpha,3);
Alpha=uint8(Alpha*255/max(Alpha,[],"all"));
if nargout>1
varargout={Alpha,Color};
else
varargout=cat(3,Alpha,Color);
end
end
function [Alpha,Color]=ChannelSplit(Image)
Alpha=Image(:,:,1);
if bitand(size(Image,3),1)
Alpha(:)=255;
Color=Image;
else
Color=Image(:,:,2:end);
end
end
function varargout = ArrayAdapt(varargin)
%将输入的所有数组每个维度扩展到所有数组在该维度的最大值
%% 可选参数
%NullValue,标量,扩展时所用的填充值,默认0
%SizeOneCopy,逻辑标量,如果一个数组某一维度尺寸为1,是否以复制而非NullValue填充的方式扩展该维度,默认false。
%% 默认参数
NullValue=0;
SizeOneCopy=false;
a=1;
while a<=length(varargin)
Argument=varargin{a};
if isstring(Argument)
varargin(a)=[];
switch Argument
case "NullValue"
NullValue=varargin{a};
case "SizeOneCopy"
SizeOneCopy=varargin{a};
end
varargin(a)=[];
else
a=a+1;
end
end
Sizer=zeros(1,1);
for a=1:length(varargin)
Sizes=num2cell(size(varargin{a}));
Sizer(Sizes{:})=0;
end
ArraySize=size(Sizer);
if SizeOneCopy
varargin=cellfun(@(Array)Soc(Array,ArraySize),varargin,"UniformOutput",false);
end
Output=cellfun(@ArrayFill,varargin,"UniformOutput",false);
if nargout>1
varargout=Output;
else
varargout={Output};
end
function Array=ArrayFill(Array)
Array=ArrayExpand(Array,ArraySize);
Array(~HasValueLogical(Array))=NullValue;
end
function Array=HasValueLogical(Array)
Array(:)=1;
Array=ArrayExpand(logical(Array),ArraySize);
end
end
function Array=ArrayExpand(Array,Sizes)
%扩展并返回数组,0填充。
if length(Sizes)>ndims(Array)||any(Sizes>size(Array))
Sizes=num2cell(Sizes);
Array(Sizes{:})=0;
end
end
function Array=Soc(Array,Sizes)
Sizes(size(Array)>1)=1;
Array=repmat(Array,Sizes);
end
使用方法:
Image1="图1.png";
Image2="图2.png";
Image1=importdata(Image1);
Image2=importdata(Image2);
%仅当原图是有Alpha通道的PNG时才需要这两行
Image1=cat(3,Image1.alpha,Image1.cdata);
Image2=cat(3,Image2.alpha,Image2.cdata);
%仅当原图是有Alpha通道的PNG时才需要这两行
[Alpha,Color]=MirageTankV2(Image1,Image2);
imwrite(Color,"幻影坦克.png","Alpha",Alpha);

More Answers (0)

Products


Release

R2019b

Community Treasure Hunt

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

Start Hunting!