initial working image resizer
authorChristian Weiske <cweiske@cweiske.de>
Thu, 16 Aug 2012 18:33:17 +0000 (20:33 +0200)
committerChristian Weiske <cweiske@cweiske.de>
Thu, 16 Aug 2012 18:33:17 +0000 (20:33 +0200)
.gitignore [new file with mode: 0644]
README.rst [new file with mode: 0644]
data/surrogator.config.php [new file with mode: 0644]
data/surrogator.config.php.dist [new file with mode: 0644]
raw/.keep [new file with mode: 0644]
surrogator.php [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..4564537
--- /dev/null
@@ -0,0 +1,2 @@
+var/*
+raw/*
diff --git a/README.rst b/README.rst
new file mode 100644 (file)
index 0000000..f4aaba4
--- /dev/null
@@ -0,0 +1,18 @@
+**********
+Surrogator
+**********
+
+Open source Libravatar__ compatible avatar image server written in PHP.
+
+__ http://wiki.libravatar.org/api/
+
+
+
+Steps
+=====
+
+1. Put images in ``raw/`` folder.
+   Name has to be email address + image file extension, for example
+   ``foo@example.org.png``.
+2. Generate/update big square files.
+3. Generate images for each size that is defined in ``$sizes``.
diff --git a/data/surrogator.config.php b/data/surrogator.config.php
new file mode 100644 (file)
index 0000000..421e057
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+$rawDir = __DIR__ . '/../raw/';
+$varDir = __DIR__ . '/../var/';
+$sizes   = array(16, 32, 48, 64, 80, 96, 128, 256, 512);
+$maxSize = 512;
+?>
diff --git a/data/surrogator.config.php.dist b/data/surrogator.config.php.dist
new file mode 100644 (file)
index 0000000..421e057
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+$rawDir = __DIR__ . '/../raw/';
+$varDir = __DIR__ . '/../var/';
+$sizes   = array(16, 32, 48, 64, 80, 96, 128, 256, 512);
+$maxSize = 512;
+?>
diff --git a/raw/.keep b/raw/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/surrogator.php b/surrogator.php
new file mode 100644 (file)
index 0000000..e48190e
--- /dev/null
@@ -0,0 +1,138 @@
+<?php
+require __DIR__ . '/data/surrogator.config.php';
+
+if (!is_dir($varDir . '/square')) {
+    mkdir($varDir . '/square', 0755, true);
+}
+foreach ($sizes as $size) {
+    if (!is_dir($varDir . '/' . $size)) {
+        mkdir($varDir . '/' . $size, 0755);
+    }
+}
+
+$dir = new RegexIterator(
+    new DirectoryIterator($rawDir),
+    '#^.+@.+\.(png|jpg)$#'
+);
+foreach ($dir as $fileInfo) {
+    $origPath   = $fileInfo->getPathname();
+    $fileName   = $fileInfo->getFilename();
+    $ext        = strtolower(substr($fileName, strrpos($fileName, '.') + 1));
+    $squarePath = $varDir . '/square/'
+        . substr($fileName, 0, -strlen($ext)) . 'png';
+
+    if (image_uptodate($origPath, $squarePath)) {
+        continue;
+    }
+
+    if (!createSquare($origPath, $ext, $squarePath, $maxSize)) {
+        continue;
+    }
+
+    list($md5, $sha256) = getHashes($fileName);
+
+    $imgSquare = imagecreatefrompng($squarePath);
+    foreach ($sizes as $size) {
+        $sizePathMd5    = $varDir . '/' . $size . '/' . $md5 . '.png';
+        $sizePathSha256 = $varDir . '/' . $size . '/' . $sha256 . '.png';
+
+        $imgSize = imagecreatetruecolor($size, $size);
+        imagealphablending($imgSize, false);
+        imagefilledrectangle(
+            $imgSize, 0, 0, $size - 1, $size - 1,
+            imagecolorallocatealpha($imgSize, 0, 0, 0, 127)
+        );
+        imagecopyresampled(
+            $imgSize, $imgSquare, 
+            0, 0, 0, 0,
+            $size, $size, $maxSize, $maxSize
+        );
+        imagesavealpha($imgSize, true);
+        imagepng($imgSize, $sizePathMd5);
+        imagepng($imgSize, $sizePathSha256);
+        imagedestroy($imgSize);
+        
+    }
+    imagedestroy($imgSquare);
+}
+
+
+function getHashes($fileName)
+{
+    $fileNameNoExt = substr($fileName, 0, -strlen(strrpos($fileName, '.')) - 2);
+    $emailAddress  = trim(strtolower($fileNameNoExt));
+
+    return array(
+        md5($emailAddress), hash('sha256', $emailAddress)
+    );
+}
+
+
+function createSquare($origPath, $ext, $targetPath, $maxSize)
+{
+    if ($ext == 'png') {
+        $imgOrig = imagecreatefrompng($origPath);
+    } else if ($ext == 'jpg' || $ext == 'jpeg') {
+        $imgOrig = imagecreatefromjpeg($origPath);
+    } else {
+        //unsupported format
+        return false;
+    }
+
+    if ($imgOrig === false) {
+        file_put_contents(
+            'php://stderr',
+            'Error loading image file: ' . $origPath
+        );
+        return false;
+    }
+
+    $imgSquare = imagecreatetruecolor($maxSize, $maxSize);
+    imagealphablending($imgSquare, false);
+    imagefilledrectangle(
+        $imgSquare, 0, 0, $maxSize - 1, $maxSize - 1,
+        imagecolorallocatealpha($imgSquare, 0, 0, 0, 127)
+    );
+    imagealphablending($imgSquare, true);
+
+    $oWidth    = imagesx($imgOrig);
+    $oHeight   = imagesy($imgOrig);
+    if ($oWidth > $oHeight) {
+        $flScale = $maxSize / $oWidth;
+    } else {
+        $flScale = $maxSize / $oHeight;
+    }
+    $nWidth  = (int)($oWidth * $flScale);
+    $nHeight = (int)($oHeight * $flScale);
+
+    imagecopyresampled(
+        $imgSquare, $imgOrig, 
+        ($maxSize - $nWidth) / 2, ($maxSize - $nHeight) / 2,
+        0, 0,
+        $nWidth, $nHeight,
+        $oWidth, $oHeight
+    );
+
+    imagesavealpha($imgSquare, true);
+    imagepng($imgSquare, $targetPath);
+
+    imagedestroy($imgSquare);
+    imagedestroy($imgOrig);
+    return true;
+}
+
+function image_uptodate($sourcePath, $targetPath)
+{
+    if (!file_exists($targetPath)) {
+        return false;
+    }
+
+    if (filemtime($sourcePath) > filemtime($targetPath)) {
+        //source newer
+        return false;
+    }
+
+    return true;
+}
+
+?>