Digital_rain_animation_medium_letters_shine.gif (500 × 400 pixels, file size: 6.49 MB, MIME type: image/gif, looped, 150 frames, 15 s)
This is a file from the Wikimedia Commons. Information from its description page there is shown below. Commons is a freely licensed media file repository. You can help. |
The Matrix Boot Camp
Summary
DescriptionDigital rain animation medium letters shine.gif |
English: Animated interpretation of digital rain (or “Matrix code“ ,“digital rain“ or sometimes „green rain“ ) from the Matrix movie series. |
Date | |
Source | Own work |
Author | Jahobr |
Other versions |
|
GIF development InfoField | |
Source code InfoField | MATLAB codefunction 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];
|
Licensing
I, the copyright holder of this work, hereby publish it under the following license:
This file is made available under the Creative Commons CC0 1.0 Universal Public Domain Dedication. | |
The person who associated a work with this deed has dedicated the work to the public domain by waiving all of their rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.
http://creativecommons.org/publicdomain/zero/1.0/deed.enCC0Creative Commons Zero, Public Domain Dedicationfalsefalse |
Items portrayed in this file
depicts
14 October 2017
image/gif
File history
Click on a date/time to view the file as it appeared at that time.
Date/Time | Thumbnail | Dimensions | User | Comment | |
---|---|---|---|---|---|
current | 21:55, 14 October 2017 | 500 × 400 (6.49 MB) | Jahobr | User created page with UploadWizard |
File usage
The following 5 pages use this file:
Global file usage
The following other wikis use this file:
- Usage on ar.wikipedia.org
- Usage on ca.wikipedia.org
- Usage on de.wikipedia.org
- Usage on en.wikiquote.org
- Usage on eo.wikiquote.org
- Usage on es.wikipedia.org
- Usage on fa.wikipedia.org
- Usage on hy.wikipedia.org
- Usage on id.wikipedia.org
- Usage on ja.wikipedia.org
- Usage on min.wikipedia.org
- Usage on ms.wikipedia.org
- Usage on ro.wikipedia.org
- Usage on ru.wikipedia.org
- Usage on tk.wikipedia.org
- Usage on tr.wikipedia.org
- Usage on vi.wikipedia.org
- Wikipedia:Bạn có biết/2020
- Thành viên:Liên minh đoàn kết các thành viên phá hoại wiki thống nhất (LTPWT)
- Thảo luận Wikipedia:Bạn có biết/2020/Tuần 33
- Cyberpunk Nhật Bản
- Ghost in the Shell (phim 1995)
- Thảo luận:Ghost in the Shell (phim 1995)
- Wikipedia:Bạn có biết/2020/Tuần 33/3
- Wikipedia:Wikipedia là một trò chơi nhập vai trực tuyến nhiều người chơi
- Bản mẫu:Game Over
- Thành viên:Thaolinh0610
- Thảo luận Thành viên:Ihsikuyr/Lưu 0
- Usage on zh-yue.wikipedia.org
- Usage on zh.wikipedia.org