File:Digital rain animation medium letters shine.gif

Digital_rain_animation_medium_letters_shine.gif (500 × 400像素,文件大小:6.49 MB,MIME类型:image/gif、​循环、​150帧、​15秒)


The Matrix Boot Camp

摘要

描述
English: Animated interpretation of digital rain (or “Matrix code“ ,“digital rain“ or sometimes „green rain“ ) from the Matrix movie series.
日期
来源 自己的作品
作者 Jahobr
其他版本
GIF开发
InfoField
 
本GIF 位图Jahobr使用MATLAB创作。
源代码
InfoField

MATLAB code

function digital_rain_animation
% Programmed in Matlab R2017a.
% You can have a glimpse of the original digital rain in the 
%   Matrix Movie at 1:04 (or youtube: /watch?v=3vAnuBtyEYE ).
% The original is far messier. Drops stop, start and shift rows
% additionally there are stuck letters, gaps and so on.
% This is not replicated because it makes the short loop time very obvious.
% Those features could be added in a longer video.
% The font is not correct.
% The code could be radically optimized, but hence it is intended for 
%   one-time use, there is no real need.

latinList = ['-><=*' char(124) '":АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ0123456789']; % the vertical bar is encrypted as char(124) to avoid template-errors on wikimedia commons
asianList = char(65393:65437); % Asian symbols; Half-width kana;
% Matlab can work with UTF-8 but M-Files are saved using ANSI. If letters are typed directly, they are lost while saving the file
charList = [latinList asianList asianList]; % aisan symbols twice as likely
nChar = numel(charList);
 
[pathstr,fname] = fileparts(which(mfilename)); % save files under the same name and at file location
 
for gifVersion = [1 2 3 4 5 6]%
    
    switch gifVersion
        case 1
            rng(1) % seed random generator to make results reproducible
            name = 'small_letters';
            nFrames = 250;
            sizeLetters = [25 42]; % [nLetterRows nLetterColumns]
            dropLength = 35; % should be adjusted with regard to nFrames and sizeLetters(1) (must be smaller as nFrames)
            doubleDropRattio = 0.5; % ratios of columns with 2 drops per loop instad of just 1
            DelayTime = 1/10; % in sec
            xLimits = [0 500]; % in pixel
            yLimits = [0 400]; % in pixel
            snapshotAtFrame = 50;
        case 2
            rng(1) % seed random generator to make results reproducible
            name = 'medium_letters';
            nFrames = 150;
            sizeLetters = [12 21]; % [nLetterRows nLetterColumns]
            dropLength = 25; % should be adjusted with regard to nFrames and sizeLetters(1) (must be smaller as nFrames)
            doubleDropRattio = 1; % ratios of columns with 2 drops per loop instad of just 1
            DelayTime = 1/10; % in sec
            xLimits = [0 500]; % in pixel
            yLimits = [0 400]; % in pixel
            snapshotAtFrame = 50;
        case 3
            rng(2) % seed random generator to make results reproducible
            name = 'medium_letters_2';
            nFrames = 191; % hight Least common multiple with 150; so combinations do no allign
            sizeLetters = [12 21]; % [nLetterRows nLetterColumns]
            dropLength = 25; % should be adjusted with regard to nFrames and sizeLetters(1) (must be smaller as nFrames)
            doubleDropRattio = 1; % ratios of columns with 2 drops per loop instad of just 1
            DelayTime = 1/10; % in sec
            xLimits = [0 500]; % in pixel
            yLimits = [0 400]; % in pixel
            snapshotAtFrame = 50;
        case 4
            rng(3) % seed random generator to make results reproducible
            name = 'medium_letters_3';
            nFrames = 229;
            sizeLetters = [12 21]; % [nLetterRows nLetterColumns]
            dropLength = 25; % should be adjusted with regard to nFrames and sizeLetters(1) (must be smaller as nFrames)
            doubleDropRattio = 1; % ratios of columns with 2 drops per loop instad of just 1
            DelayTime = 1/10; % in sec
            xLimits = [0 500]; % in pixel
            yLimits = [0 400]; % in pixel
            snapshotAtFrame = 50;
        case 5
            rng(4) % seed random generator to make results reproducible
            name = 'medium_letters_4';
            nFrames = 259;
            sizeLetters = [12 21]; % [nLetterRows nLetterColumns]
            dropLength = 25; % should be adjusted with regard to nFrames and sizeLetters(1) (must be smaller as nFrames)
            doubleDropRattio = 1; % ratios of columns with 2 drops per loop instad of just 1
            DelayTime = 1/10; % in sec
            xLimits = [0 500]; % in pixel
            yLimits = [0 400]; % in pixel
            snapshotAtFrame = 50;
        case 6
            rng(1) % seed random generator to make results reproducible
            name = 'big_letters';
            nFrames = 60;
            sizeLetters = [6 9]; % [nLetterRows nLetterColumns]
            dropLength = 15; % should be adjusted with regard to nFrames and sizeLetters(1) (must be smaller as nFrames)
            doubleDropRattio = 1; % ratios of columns with 2 drops per loop instad of just 1
            DelayTime = 1/5; % in sec
            xLimits = [0 400]; % in pixel
            yLimits = [0 400]; % in pixel
            snapshotAtFrame = 50;
        otherwise
            error('not defined')
    end
 
    figHandle = figure(1562134155);
    clf
    axesHandle = axes;
    hold(axesHandle,'on')
    set(figHandle, 'Units','pixel');
    set(figHandle, 'Position',[1 1 xLimits(2) yLimits(2)]); % big start image for antialiasing later [x y width height]
    set(axesHandle,'Color',[0 0 0]); % black background
    set(axesHandle,'Position',[0 0 1 1]); % stretch axis as big as figure, [x y width height]
    set(axesHandle,'XTick',NaN) % get rid of ticks
    set(axesHandle,'YTick',NaN) % get rid of ticks
    set(axesHandle,'TickLength',[0 0]) % get rid of ticks
    set(axesHandle,'YColor',[0 0 0]) % remove outline
    set(axesHandle,'XColor',[0 0 0]) % remove outline
    
    xlim(xLimits);ylim(yLimits);
    
    letterCube = repmat(randi(nChar,sizeLetters),1,1,nFrames);
    for iRand = 1:numel(letterCube)*0.02 % small proportion of flipping symbols
        letterRow = randi(sizeLetters(1)); % select random position
        letterCol = randi(sizeLetters(2)); % select random position
        letterThroughTime = letterCube(letterRow,letterCol,:); % extract
        letterThroughTime = letterThroughTime(:)';
        letterThroughTime(1:randi(round(nFrames/3)+3,1,2)) = randi(nChar); % add a random section
        shift = randi(nFrames-1);
        letterThroughTime = [letterThroughTime(shift+1:end) letterThroughTime(1:shift)]; % time offset
        letterCube(letterRow,letterCol,:) = letterThroughTime; % write back
    end
 
    dropColMap = zeros(nFrames,3); % default Black
    dropColMap(1:dropLength,:) = letterColMap(dropLength); % drop colors with black to fill the list up
    
    glareColMap = zeros(nFrames,3); % default Black
    glareColMap(1,:) = 1; % drop tip white
    
    % for i=1:xLimits(2)
    %     plot(i,100,'.','Color',map(i,:))
    % end
    
    xDelta = xLimits(2)/sizeLetters(2);
    xCoordinates = (xDelta/2:xDelta:xLimits(2));
    
    yDelta = yLimits(2)/sizeLetters(1);
    yCoordinates = (yDelta/2:yDelta:yLimits(2))+yDelta/10;
    
    handMat = NaN(sizeLetters);
    for iRow = 1:sizeLetters(1)
        for iCol = 1:sizeLetters(2)
            handMat(iRow,iCol) = text(xCoordinates(iCol),yCoordinates(iRow),...
                charList(letterCube(iRow,iCol,1)),...
                'FontWeight','bold',...
                'FontName','monospaced',...
                'Color',[1 1 1],...
                'FontUnits','pixel',...
                'FontSize',yDelta*1.08,...
                'HorizontalAlignment','center',...
                'VerticalAlignment','middle');
        end
    end
    stateMat = repmat((1:sizeLetters(1))' ,1, sizeLetters(2)); % initiate the basic rain drops running down the screen
    stateOffset = randi(nFrames,1,sizeLetters(2)); % create a basic offsets for different delays
    stateMat = stateMat + ones(sizeLetters(1),1) * stateOffset;
    
    
    stateOffset = randi(round(nFrames/3),1,sizeLetters(2))+randi(round(nFrames/5),1,sizeLetters(2)); % create secondary offsets for different delays
    stateOffset(rand(1,sizeLetters(2))>doubleDropRattio) = 0; % only a portion of columns get 2 drops
    stateMat2 = stateMat + ones(sizeLetters(1),1) * stateOffset;
    
    clearRGBimage = uint8(ones(yLimits(2),xLimits(2),3,nFrames)); % allocate
    shineRGBimage = clearRGBimage;                                      % allocate
 
    for iFrame = 1:nFrames
        
        stateMat  = rem(stateMat ,nFrames); % bring back into range [0 nFrames-1]
        stateMat2 = rem(stateMat2,nFrames); % bring back into range [0 nFrames-1]
        
        for iRow = 1:sizeLetters(1)
            for iCol = 1:sizeLetters(2)
                if stateMat(iRow,iCol)>stateMat2(iRow,iCol) % use the second drop
                    set(handMat(iRow,iCol),'Color',dropColMap(stateMat2(iRow,iCol)+1,:),...
                        'string',charList(nChar-letterCube(iRow,iCol,iFrame)+1)); % use a mirrored charList to get different characters
                else  % use the first drop
                    set(handMat(iRow,iCol),'Color',dropColMap(stateMat(iRow,iCol)+1,:),...
                        'string',charList(letterCube(iRow,iCol,iFrame)));
                end
            end
        end
        drawnow
        fClear = getframe(figHandle);
        
        % secondary image using only the white letters to generate extra strong glare
        for iRow = 1:sizeLetters(1)
            for iCol = 1:sizeLetters(2)
                if stateMat(iRow,iCol)>stateMat2(iRow,iCol) % use the second drop
                    set(handMat(iRow,iCol),'Color',glareColMap(stateMat2(iRow,iCol)+1,:),...
                        'string',charList(nChar-letterCube(iRow,iCol,iFrame)+1)); % use a mirrored charList to get different characters
                else  % use the first drop
                    set(handMat(iRow,iCol),'Color',glareColMap(stateMat(iRow,iCol)+1,:),...
                        'string',charList(letterCube(iRow,iCol,iFrame)));
                end
            end
        end
        drawnow
        fGlare = getframe(figHandle);
        
        stateMat  = stateMat +1; % move drops "one position down"
        stateMat2 = stateMat2+1; % move drops "one position down"
        
        %% save animation
        fClear.cdata = fliplr(fClear.cdata); % view from "behind the code"
        fGlare.cdata = fliplr(fGlare.cdata); % view from "behind the code"
        
        weightFiddleMode = false; % for debugging ad adjusting
        
        if weightFiddleMode; figure(110); clf; imshow(fClear.cdata); end
        fShine.cdata = imgaussfilt(fClear.cdata,yDelta/3); % far reaching shine of all letters
        if weightFiddleMode; figure(111); clf; imshow(fShine.cdata); end
        fShine.cdata = fShine.cdata*1.5; % make brighter (automatically limited to range by unit8 format)
        if weightFiddleMode; figure(112); clf; imshow(fShine.cdata); end
        
        fEdge.cdata = imgaussfilt(fClear.cdata,yDelta/12); % stronger glow close to the letter edges
        if weightFiddleMode; figure(113); clf; imshow(fEdge.cdata); end
        
        fEdge.cdata = fEdge.cdata*0.7; % make darker
        if weightFiddleMode; figure(114); clf; imshow(fEdge.cdata); end
        
        fShine.cdata = imadd(fShine.cdata,fEdge.cdata); % combine shine and edge glow
        if weightFiddleMode; figure(115); clf; imshow(fShine.cdata); end
        
        
        if weightFiddleMode; figure(116); clf; imshow(fGlare.cdata); end
        fGlare.cdata = imgaussfilt(fGlare.cdata,yDelta/2); % far reaching shine of the white letter at the drop tip
        if weightFiddleMode; figure(117); clf; imshow(fGlare.cdata); end
        fGlare.cdata = fGlare.cdata*1.5; % make brighter (automatically limited to range by unit8 format)
        if weightFiddleMode; figure(118); clf; imshow(fGlare.cdata); end
        
        fShine.cdata = imadd(fShine.cdata,fGlare.cdata); % combine; this makes the drop tip double bright
        if weightFiddleMode; figure(119); clf; imshow(fShine.cdata); end
        
        fShine.cdata = imadd(fShine.cdata*0.8,fClear.cdata*0.5);  % combine shine with original sharp letters
        if weightFiddleMode; figure(120); clf; imshow(fShine.cdata); end
        if weightFiddleMode; return; end
 
        clearRGBimage(:,:,:,iFrame) = fClear.cdata; % store
        shineRGBimage(:,:,:,iFrame) = fShine.cdata; % store
        
        if snapshotAtFrame == iFrame
            imwrite(fClear.cdata,fullfile(pathstr, [fname '_' name '_clear.png'])) % save png (native RGB no colormap)
            imwrite(fShine.cdata,fullfile(pathstr, [fname '_' name '_shine.png'])) % save png (native RGB no colormap)
        end
    end
     
    colormapImage = permute(clearRGBimage(:,:,:,:),[1 2 4 3]); % step1; make unified image
    colormapImage = reshape(colormapImage, yLimits(2),xLimits(2)*nFrames,3,1); % step2; make unified image
    mapClear = createImMap(colormapImage,64,[0 0 0; 1 1 1]); % colormap
    colormapImage = permute(shineRGBimage(:,:,:,:),[1 2 4 3]); % step1; make unified image
    colormapImage = reshape(colormapImage, yLimits(2),xLimits(2)*nFrames,3,1); % step2; make unified image
    mapShine = createImMap(colormapImage,128,[0 0 0; 1 1 1]); % colormap
    
    imClear = uint8(ones(yLimits(2),xLimits(2),1,nFrames)); % allocate
    imShine = uint8(ones(yLimits(2),xLimits(2),1,nFrames)); % allocate
    for iFrame = 1:nFrames
        imClear(:,:,1,iFrame) = rgb2ind(clearRGBimage(:,:,:,iFrame),mapClear); % ,'nodither');
        imShine(:,:,1,iFrame) = rgb2ind(shineRGBimage(:,:,:,iFrame),mapShine); % ,'nodither');
    end

        imwrite(imClear,mapClear,fullfile(pathstr, [fname '_' name '_clear.gif']),'DelayTime',DelayTime,'LoopCount',inf) % save gif
        imwrite(imShine,mapShine,fullfile(pathstr, [fname '_' name '_shine.gif']),'DelayTime',DelayTime,'LoopCount',inf) % save gif
        disp([fname '_' name '_clear.gif  has ' num2str(numel(imClear)/10^6 ,4) ' Megapixels']) % Category:Animated GIF files exceeding the 50 MP limit
end
 
function map = letterColMap(nCol)
%  map:
% Pos 1:  white (short burst)
% a: bright green changing to green
% b: staying green ()
% c: fading to black
 
querries = linspace(0,100,nCol-1);
 
x = [0   15   40   100]; % percent of map
%      a    b    c 
red = interp1(x,... 
    [0.4  0.0  0.0   0],... intensity
    querries);
blue = interp1(x,... 
    [0.4  0.0  0.0   0],... intensity
    querries);
green = interp1(x,... 
    [1   0.8   0.8   0],... intensity
    querries);
 
map = [ [1 1 1];red(:) green(:) blue(:)]; % white in front


function map = createImMap(imRGB,nCol,startMap)
% createImMap creates a color-map including predefined colors.
% "rgb2ind" creates a map but there is no option to predefine some colors,
%         and it does not handle stacked images.
% Input:
%   imRGB:     image, [imRows x imColumns x 3(RGB) x nStack] (unit8)
%   nCol:      total number of colors the map should have, [integer]
%   startMap:  predefined colors; colormap format, [p x 3] (double)

imRGB = permute(imRGB,[1 2 4 3]); % step1; make unified column-image (handling possible nStack)
imRGBcolumn = reshape(imRGB,[],1,3,1); % step2; make unified column-image

fullMap = double(permute(imRGBcolumn,[1 3 2]))./255; % "column image" to color map 
[fullMap,~,imMapColumn] = unique(fullMap,'rows'); % find all unique colors; create indexed colormap-image
% "cmunique" could be used but is buggy and inconvenient because the output changes between "uint8" and "double"

nColFul = size(fullMap,1);
nColStart = size(startMap,1);
disp(['Number of colors: ' num2str(nColFul) ' (including ' num2str(nColStart) ' self defined)']);

if nCol<=nColStart;  error('Not enough colors');        end
if nCol>nColFul;   warning('More colors than needed');  end

isPreDefCol = false(size(imMapColumn)); % init
 
for iCol = 1:nColStart
    diff = sum(abs(fullMap-repmat(startMap(iCol,:),nColFul,1)),2); % difference between a predefined and all colors
    [mDiff,index] = min(diff); % find matching (or most similar) color
    if mDiff>0.05 % color handling is not precise
        warning(['Predefined color ' num2str(iCol) ' does not appear in image'])
        continue
    end
    isThisPreDefCol = imMapColumn==index; % find all pixel with predefined color
    disp([num2str(sum(isThisPreDefCol(:))) ' pixel have predefined color ' num2str(iCol)]);
    isPreDefCol = or(isPreDefCol,isThisPreDefCol); % combine with overall list
end
[~,mapAdditional] = rgb2ind(imRGBcolumn(~isPreDefCol,:,:),nCol-nColStart,'nodither'); % create map of remaining colors
map = [startMap;mapAdditional];

许可协议

我,本作品著作权人,特此采用以下许可协议发表本作品:
Creative Commons CC-Zero 本作品采用知识共享CC0 1.0 通用公有领域贡献许可协议授权。
采用本宣告发表本作品的人,已在法律允许的范围内,通过在全世界放弃其对本作品拥有的著作权法规定的所有权利(包括所有相关权利),将本作品贡献至公有领域。您可以复制、修改、传播和表演本作品,将其用于商业目的,无需要求授权。

说明

添加一行文字以描述该文件所表现的内容
Govt. Holkar College

此文件中描述的项目

描绘内容

image/gif

文件历史

点击某个日期/时间查看对应时刻的文件。

日期/时间缩⁠略⁠图大小用户备注
当前2017年10月14日 (六) 21:552017年10月14日 (六) 21:55版本的缩略图500 × 400(6.49 MB)JahobrUser created page with UploadWizard

以下3个页面使用本文件:

全域文件用途

以下其他wiki使用此文件: