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
摘要
描述Digital 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. |
日期 | |
來源 | 自己的作品 |
作者 | Jahobr |
其他版本 |
|
GIF開發 InfoField | |
原始碼 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];
|
授權條款
我,本作品的著作權持有者,決定用以下授權條款發佈本作品:
此檔案在創用CC CC0 1.0 通用公有領域貢獻宣告之下分發。 | |
在此宣告之下分發本作品者,已依據各國著作權法,在全世界放棄其對本作品所擁有的著作權及所有相關相似的法律權利,從而將本作品貢獻至公有領域。您可以複製、修改、分發和演示該作品,用於任何商業用途,所有這些都不需要請求授權。
http://creativecommons.org/publicdomain/zero/1.0/deed.enCC0Creative Commons Zero, Public Domain Dedicationfalsefalse |
在此檔案描寫的項目
描繪內容
著作權狀態 繁體中文 (已轉換拼寫)
保有知識產權並由其所有者公開於公有領域 繁體中文 (已轉換拼寫)
14 10 2017
多媒體型式 繁體中文 (已轉換拼寫)
image/gif
檔案歷史
點選日期/時間以檢視該時間的檔案版本。
日期/時間 | 縮圖 | 尺寸 | 用戶 | 備註 | |
---|---|---|---|---|---|
目前 | 2017年10月14日 (六) 21:55 | 500 × 400(6.49 MB) | Jahobr | User created page with UploadWizard |
檔案用途
下列3個頁面有用到此檔案:
全域檔案使用狀況
以下其他 wiki 使用了這個檔案:
- ar.wikipedia.org 的使用狀況
- ca.wikipedia.org 的使用狀況
- de.wikipedia.org 的使用狀況
- en.wikipedia.org 的使用狀況
- en.wikiquote.org 的使用狀況
- eo.wikiquote.org 的使用狀況
- es.wikipedia.org 的使用狀況
- fa.wikipedia.org 的使用狀況
- hy.wikipedia.org 的使用狀況
- id.wikipedia.org 的使用狀況
- ja.wikipedia.org 的使用狀況
- min.wikipedia.org 的使用狀況
- ms.wikipedia.org 的使用狀況
- ro.wikipedia.org 的使用狀況
- ru.wikipedia.org 的使用狀況
- tk.wikipedia.org 的使用狀況
- tr.wikipedia.org 的使用狀況
- 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
- zh-yue.wikipedia.org 的使用狀況