Last active
August 29, 2015 13:56
-
-
Save johnnoel/9079452 to your computer and use it in GitHub Desktop.
Creates "barcode" style images from video files, kind of like http://moviebarcode.tumblr.com/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$videoFiles = array(); | |
if ($_SERVER['argc'] <= 1) { | |
die('No files passed in command line'); | |
} | |
array_shift($_SERVER['argv']); | |
$videoFiles = $_SERVER['argv']; | |
sort($videoFiles); | |
foreach ($videoFiles as $videoFile) { | |
if (!file_exists($videoFile)) { | |
die(sprintf('Unable to read file %s', $videoFiles)); | |
} | |
$hash = hash('md5', $videoFile); | |
$path = dirname($videoFile).DIRECTORY_SEPARATOR.$hash.DIRECTORY_SEPARATOR; | |
if ((file_exists($path) && !is_dir($path)) || (!file_exists($path) && !mkdir($path))) { | |
die(sprintf('Unable to create directory %s', $path)); | |
} | |
shell_exec('ffmpeg -i '.escapeshellarg($videoFile).' -q:v 1 "'.$path.'img%06d.jpg"'); | |
shell_exec('gm mogrify -resize 1x720! -format png "'.$path.'\\*.jpg"'); | |
$pngFiles = array(); | |
$di = new DirectoryIterator($path); | |
foreach ($di as $file) { | |
if ($file->isDot() || $file->isDir()) { | |
continue; | |
} | |
$ext = pathinfo($file->getPathname(), PATHINFO_EXTENSION); | |
if (strtolower($ext) === 'png') { | |
$pngFiles[] = $file->getPathname(); | |
} | |
} | |
$total = count($pngFiles); | |
$batch = 1000; | |
$comboFiles = array(); | |
for ($i = 0; $i <= $total; $i += $batch) { | |
$batchStr = sprintf('%06d', $i).'-'.sprintf('%06d', ($i + $batch)); | |
$batchPath = $path.$batchStr.DIRECTORY_SEPARATOR; | |
if (!file_exists($batchPath) && !mkdir($batchPath)) { | |
die('Unable to create directory (batch)'); | |
} | |
sort($pngFiles); | |
$batchFiles = array_splice($pngFiles, 0, $batch); | |
foreach ($batchFiles as $file) { | |
rename($file, $batchPath.basename($file)); | |
} | |
shell_exec('gm montage +frame +shadow +label -tile '.$batch.'x1 -geometry +0+0 "'.$batchPath.'*.png" "'.$path.$batchStr.'.png"'); | |
$comboFiles[] = $batchStr.'.png'; | |
} | |
$comboPath = $path.'combo'.DIRECTORY_SEPARATOR; | |
if (!file_exists($comboPath) && !mkdir($comboPath)) { | |
die('Unable to create directory (combo)'); | |
} | |
foreach ($comboFiles as $comboFile) { | |
rename($path.$comboFile, $comboPath.$comboFile); | |
} | |
shell_exec('gm montage +frame +shadow +label -tile '.count($comboFiles).'x1 -geometry +0+0 "'.$comboPath.'*.png" "'.$path.'\\max.png"'); | |
shell_exec('gm convert -resize 1280x720! "'.$path.'\\max.png" "'.dirname($videoFile).'\\'.pathinfo($videoFile, PATHINFO_FILENAME).'.png"'); | |
shell_exec('rmdir /S /Q '.$path); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function rgb($int) { | |
$r = ($int >> 16) & 0xFF; | |
$g = ($int >> 8) & 0xFF; | |
$b = $int & 0xFF; | |
return array($r, $g, $b); | |
} | |
function hsl($a) { | |
//http://stackoverflow.com/questions/11923659/javascript-sort-rgb-values | |
list($r, $g, $b) = rgb($a); | |
$max = max($r, $g, $b); | |
$min = min($r, $g, $b); | |
$h = $s = $l = ($max + $min) / 2; | |
if ($max == $min) { | |
$h = $s = 0; | |
} else { | |
$d = $max - $min; | |
if ($l > 0.5) { | |
$tmp = (2 - $max - $min); | |
$s = ($tmp === 0) ? 0 : $d / $tmp; | |
} else { | |
$s = ($d / ($max + $min)); | |
} | |
switch ($max) { | |
case $r: | |
$h = ($g - $b) / $d + (($g < $b) ? 6 : 0); | |
break; | |
case $g: | |
$h = ($b - $r) / $d + 2; | |
break; | |
case $b: | |
$h = ($r - $g) / $d + 4; | |
break; | |
} | |
$h /= 6; | |
} | |
return array($h, $s, $l); | |
} | |
function sort_basic($a, $b) { | |
if ($a[2] == $b[2]) { | |
return 0; | |
} | |
return ($a[2] < $b[2]) ? -1 : 1; | |
} | |
function sort_brightness($a, $b) { | |
list($ar, $ag, $ab) = rgb($a[2]); | |
list($br, $bg, $bb) = rgb($b[2]); | |
$brightnessA = ($ar + $ag + $ab) / 3; | |
$brightnessB = ($br + $bg + $bb) / 3; | |
if ($brightnessA == $brightnessB) { | |
return 0; | |
} | |
return ($brightnessA < $brightnessB) ? -1 : 1; | |
} | |
function sort_luminance($a, $b) { | |
list($ar, $ag, $ab) = rgb($a[2]); | |
list($br, $bg, $bb) = rgb($b[2]); | |
$luminanceA = (0.2126 * $ar) + (0.7152 * $ag) + (0.0722 * $ab); | |
$luminanceB = (0.2126 * $br) + (0.7152 * $bg) + (0.0722 * $bb); | |
if ($luminanceA == $luminanceB) { | |
return 0; | |
} | |
return ($luminanceA < $luminanceB) ? -1 : 1; | |
} | |
function sort_hue($a, $b) { | |
list($ar, $ag, $ab) = rgb($a[2]); | |
list($br, $bg, $bb) = rgb($b[2]); | |
$hueA = atan2(sqrt(3) * ($ag - $ab), 2 * ($ar - $ag - $ab)); | |
$hueB = atan2(sqrt(3) * ($bg - $bb), 2 * ($br - $bg - $bb)); | |
if ($hueA == $hueB) { | |
return 0; | |
} | |
return ($hueA < $hueB) ? -1 : 1; | |
} | |
function sort_hsl($a, $b) { | |
list ($ah, $as, $al) = hsl($a[2]); | |
list ($bh, $bs, $bl) = hsl($b[2]); | |
if ($ah == $bh) { | |
if ($as == $bs) { | |
if ($al == $bl) { | |
return 0; | |
} | |
return ($al < $bl) ? -1 : 1; | |
} | |
return ($as < $bs) ? -1 : 1; | |
} | |
return ($ah < $bh) ? -1 : 1; | |
} | |
function sort_hls($a, $b) { | |
list ($ah, $as, $al) = hsl($a[2]); | |
list ($bh, $bs, $bl) = hsl($b[2]); | |
if ($ah == $bh) { | |
if ($al == $bl) { | |
if ($as == $bs) { | |
return 0; | |
} | |
return ($as < $bs) ? -1 : 1; | |
} | |
return ($al < $bl) ? -1 : 1; | |
} | |
return ($ah < $bh) ? -1 : 1; | |
} | |
function sort_lhs($a, $b) { | |
list ($ah, $as, $al) = hsl($a[2]); | |
list ($bh, $bs, $bl) = hsl($b[2]); | |
if ($al == $bl) { | |
if ($ah == $bh) { | |
if ($as == $bs) { | |
return 0; | |
} | |
return ($as < $bs) ? -1 : 1; | |
} | |
return ($ah < $bh) ? -1 : 1; | |
} | |
return ($al < $bl) ? -1 : 1; | |
} | |
function sort_lsh($a, $b) { | |
list ($ah, $as, $al) = hsl($a[2]); | |
list ($bh, $bs, $bl) = hsl($b[2]); | |
if ($al == $bl) { | |
if ($as == $bs) { | |
if ($ah == $bh) { | |
return 0; | |
} | |
return ($ah < $bh) ? -1 : 1; | |
} | |
return ($as < $bs) ? -1 : 1; | |
} | |
return ($al < $bl) ? -1 : 1; | |
} | |
$file = '[rori] Hentai Ouji to Warawanai Neko - 01 [76056615].png'; | |
$sorts = array('basic', 'brightness', 'luminance', 'hue', 'hsl', 'lhs', 'lsh', 'hls'); | |
$modes = array('stretch', 'column', 'pixel'); | |
$gdOrig = imagecreatefrompng($file); | |
$w = imagesx($gdOrig); $h = imagesy($gdOrig); | |
foreach ($modes as $mode) { | |
$pixels = array(); | |
$gdTmp = null; | |
echo $mode.':'.PHP_EOL; | |
switch ($mode) { | |
case 'pixel': | |
for ($x = 0; $x < $w; $x++) { | |
for ($y = 0; $y < $h; $y++) { | |
$pixels[] = array($x, $y, imagecolorat($gdOrig, $x, $y)); | |
} | |
} | |
break; | |
case 'column': | |
case 'stretch': | |
shell_exec('gm convert -resize '.$w.'x1! '.escapeshellarg($file).' tmp.png'); | |
$gdTmp = imagecreatefrompng('tmp.png'); | |
for ($x = 0; $x < $w; $x++) { | |
$pixels[] = array($x, 0, imagecolorat($gdTmp, $x, 0)); | |
} | |
break; | |
} | |
foreach ($sorts as $sort) { | |
echo $sort.PHP_EOL; | |
$gdNew = imagecreatetruecolor($w, $h); | |
usort($pixels, 'sort_'.$sort); | |
switch ($mode) { | |
case 'pixel': | |
for ($x = 0; $x < $w; $x++) { | |
for ($y = 0; $y < $h; $y++) { | |
$offset = ($x * $h) + $y; | |
$pixel = $pixels[$offset]; | |
list($r, $g, $b) = rgb($pixel[2]); | |
$colour = imagecolorallocate($gdNew, $r, $g, $b); | |
imagesetpixel($gdNew, $x, $y, $colour); | |
} | |
} | |
break; | |
case 'column': | |
foreach ($pixels as $k => $v) { | |
// $k = newpos | |
// $v[0] = oldpos | |
imagecopy($gdNew, $gdOrig, $k, 0, $v[0], 0, 1, $h); | |
} | |
break; | |
case 'stretch': | |
foreach ($pixels as $k => $v) { | |
imagecopyresized($gdNew, $gdTmp, $k, 0, $v[0], 0, 1, $h, 1, 1); | |
} | |
break; | |
} | |
$name = $mode.'-'.$sort.'.png'; | |
imagepng($gdNew, $name); | |
imagedestroy($gdNew); | |
} | |
if ($gdTmp !== null) { | |
imagedestroy($gdTmp); | |
$gdTmp = null; | |
unlink('tmp.png'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment