Zum Inhalt springen

Datei:Digital rain animation medium letters shine.gif

aus AufEinWort, der freien Forschung
    Originaldatei (500 × 400 Pixel, Dateigröße: 6,49 MB, MIME-Typ: image/gif, Endlosschleife, 150 Bilder, 15 s)
    Hinweis: Aufgrund technischer Beschränkungen werden Vorschaubilder hochauflösender GIF-Dateien wie dieser nicht animiert.

    Diese Datei stammt aus Wikimedia Commons und kann von anderen Projekten verwendet werden. Die Beschreibung von deren Dateibeschreibungsseite wird unten angezeigt.

    Beschreibung

    Beschreibung
    English: Animated interpretation of digital rain (or “Matrix code“ ,“digital rain“ or sometimes „green rain“ ) from the Matrix movie series.
    Datum
    Quelle Eigenes Werk
    Urheber Jahobr
    Andere Versionen
    GIF‑Erstellung
    InfoField
     Dieses Diagramm wurde von Jahobr mit MATLAB erstellt.
    Quelltext
    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];
    

    Lizenz

    Ich, der Urheber dieses Werkes, veröffentliche es unter der folgenden Lizenz:
    Creative Commons CC-Zero Diese Datei wird unter der Creative-Commons-Lizenz CC0 1.0 Verzicht auf das Copyright zur Verfügung gestellt.
    Die Person, die das Werk mit diesem Dokument verbunden hat, übergibt dieses weltweit der Gemeinfreiheit, indem sie alle Urheberrechte und damit verbundenen weiteren Rechte – im Rahmen der jeweils geltenden gesetzlichen Bestimmungen – aufgibt. Das Werk kann – selbst für kommerzielle Zwecke – kopiert, modifiziert und weiterverteilt werden, ohne hierfür um Erlaubnis bitten zu müssen.

    Kurzbeschreibungen

    Ergänze eine einzeilige Erklärung, was diese Datei darstellt.
    Govt. Holkar College

    In dieser Datei abgebildete Objekte

    Motiv

    image/gif

    6.808.131 Byte

    400 Pixel

    500 Pixel

    3ab14df29f2155a51a6c21d33b4227beb7ef2b90

    Dateiversionen

    Klicke auf einen Zeitpunkt, um diese Version zu laden.

    Version vomVorschaubildMaßeBenutzerKommentar
    aktuell22:55, 14. Okt. 2017Vorschaubild der Version vom 22:55, 14. Okt. 2017500 × 400 (6,49 MB)wikimediacommons>JahobrUser created page with UploadWizard

    Die folgende Seite verwendet diese Datei: