Skip to content

Commit

Permalink
gif preview
Browse files Browse the repository at this point in the history
  • Loading branch information
muelea committed Jun 15, 2023
1 parent bc85883 commit 496642f
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 0 deletions.
114 changes: 114 additions & 0 deletions htmlpreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
(function () {

var previewForm = document.getElementById('previewform');

var url = location.search.substring(1).replace(/\/\/github\.com/, '//raw.githubusercontent.com').replace(/\/blob\//, '/'); //Get URL of the raw file

var replaceAssets = function () {
var frame, a, link, links = [], script, scripts = [], i, href, src;
//Framesets
if (document.querySelectorAll('frameset').length)
return; //Don't replace CSS/JS if it's a frameset, because it will be erased by document.write()
//Frames
frame = document.querySelectorAll('iframe[src],frame[src]');
for (i = 0; i < frame.length; ++i) {
src = frame[i].src; //Get absolute URL
if (src.indexOf('//raw.githubusercontent.com') > 0 || src.indexOf('//bitbucket.org') > 0) { //Check if it's from raw.github.com or bitbucket.org
frame[i].src = '//' + location.hostname + location.pathname + '?' + src; //Then rewrite URL so it can be loaded using CORS proxy
}
}
//Links
a = document.querySelectorAll('a[href]');
for (i = 0; i < a.length; ++i) {
href = a[i].href; //Get absolute URL
if (href.indexOf('#') > 0) { //Check if it's an anchor
a[i].href = '//' + location.hostname + location.pathname + location.search + '#' + a[i].hash.substring(1); //Then rewrite URL with support for empty anchor
} else if ((href.indexOf('//raw.githubusercontent.com') > 0 || href.indexOf('//bitbucket.org') > 0) && (href.indexOf('.html') > 0 || href.indexOf('.htm') > 0)) { //Check if it's from raw.github.com or bitbucket.org and to HTML files
a[i].href = '//' + location.hostname + location.pathname + '?' + href; //Then rewrite URL so it can be loaded using CORS proxy
}
}
//Stylesheets
link = document.querySelectorAll('link[rel=stylesheet]');
for (i = 0; i < link.length; ++i) {
href = link[i].href; //Get absolute URL
if (href.indexOf('//raw.githubusercontent.com') > 0 || href.indexOf('//bitbucket.org') > 0) { //Check if it's from raw.github.com or bitbucket.org
links.push(fetchProxy(href, null, 0)); //Then add it to links queue and fetch using CORS proxy
}
}
Promise.all(links).then(function (res) {
for (i = 0; i < res.length; ++i) {
loadCSS(res[i]);
}
});
//Scripts
script = document.querySelectorAll('script[type="text/htmlpreview"]');
for (i = 0; i < script.length; ++i) {
src = script[i].src; //Get absolute URL
if (src.indexOf('//raw.githubusercontent.com') > 0 || src.indexOf('//bitbucket.org') > 0) { //Check if it's from raw.github.com or bitbucket.org
scripts.push(fetchProxy(src, null, 0)); //Then add it to scripts queue and fetch using CORS proxy
} else {
script[i].removeAttribute('type');
scripts.push(script[i].innerHTML); //Add inline script to queue to eval in order
}
}
Promise.all(scripts).then(function (res) {
for (i = 0; i < res.length; ++i) {
loadJS(res[i]);
}
document.dispatchEvent(new Event('DOMContentLoaded', {bubbles: true, cancelable: true})); //Dispatch DOMContentLoaded event after loading all scripts
});
};

var loadHTML = function (data) {
if (data) {
data = data.replace(/<head([^>]*)>/i, '<head$1><base href="' + url + '">').replace(/<script(\s*src=["'][^"']*["'])?(\s*type=["'](text|application)\/javascript["'])?/gi, '<script type="text/htmlpreview"$1'); //Add <base> just after <head> and replace <script type="text/javascript"> with <script type="text/htmlpreview">
setTimeout(function () {
document.open();
document.write(data);
document.close();
replaceAssets();
}, 10); //Delay updating document to have it cleared before
}
};

var loadCSS = function (data) {
if (data) {
var style = document.createElement('style');
style.innerHTML = data;
document.head.appendChild(style);
}
};

var loadJS = function (data) {
if (data) {
var script = document.createElement('script');
script.innerHTML = data;
document.body.appendChild(script);
}
};

var fetchProxy = function (url, options, i) {
var proxy = [
'', // try without proxy first
'https://api.codetabs.com/v1/proxy/?quest='
];
return fetch(proxy[i] + url, options).then(function (res) {
if (!res.ok) throw new Error('Cannot load ' + url + ': ' + res.status + ' ' + res.statusText);
return res.text();
}).catch(function (error) {
if (i === proxy.length - 1)
throw error;
return fetchProxy(url, options, i + 1);
})
};

if (url && url.indexOf(location.hostname) < 0)
fetchProxy(url, null, 0).then(loadHTML).catch(function (error) {
console.error(error);
previewForm.style.display = 'block';
previewForm.innerText = error;
});
else
previewForm.style.display = 'block';

})()
Binary file added media/projectpage/samples.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions scripts/gifs_to_mp4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import os
import imageio
import numpy as np
from PIL import Image, ImageSequence

# Specify the folder path, number of rows, and number of columns
folder_path = "media/projectpage/sample"
rows = 4
columns = 5

def create_gif_array(folder_path, rows, columns):
# Get all gif files in the folder
gif_files = [file for file in os.listdir(folder_path) if file.endswith(".gif")]
num_gifs = rows * columns

# Sort the files in alphabetical order
gif_files.sort()

# Create an empty list to store the frames
frames = []

for gif_idx, file in enumerate(gif_files[:num_gifs]):
# Read the GIF file using imageio
gif_path = os.path.join(folder_path, file)
gif_frames = imageio.v3.imread(gif_path, index=None)

# Append the frames to the list
frames.append(gif_frames)

frames = np.array(frames)
# reorder dimsions in frames to be (num_gifs, height, width, num_frames, channels)
frames = np.transpose(frames, (0,2,3,1,4)).reshape(rows, columns, 256, 200, 30, 3)

# concatenate the first four dimensions to create array of shape 3 * 256, 5 * 200, 30, 3
array = np.concatenate(np.concatenate(frames, axis=1), axis=1)
array = np.transpose(array, (2,0,1,3))

# Save the array gif
imageio.mimwrite(f"{folder_path}/samples.gif", array, fps=8)

# Call the function to create the gif array and save it as an mp4 file
create_gif_array(folder_path, rows, columns)

0 comments on commit 496642f

Please sign in to comment.