Divergenzmeter
Ich hab mich mal aus Langeweile (und zur Übung) an ein Divergenzmeter auf php-Basis gesetzt und eigentlich wäre es zu schade, wenn ich es nicht sharen würde.
Sorry, wenn das nicht 100%ig in den Thread passt, aber ein eingener dafür wäre mir ein bisschen 0518 und so. Ein Mod kann es ja in einen neuen Thread schieben.
What is it?
[Only registered and activated users can see links. Click Here To Register...]
Es wird eine mit einem einfachen Algorhytmus (falls man das so nennen kann) zufällige Zahl zwischen 0 und 1.8 generiert und anschließend als Bild angezeigt.
Usage
Benutzbar als
[IMG]http://fichtefoll.dyndns.org/divmet/[/IMG].
Solltet ihr einen
eigenen Webserver haben, könnt ihr ruhig den Source übernehmen und dort hosten, um diesen hier zu
entlasten.
Solltet ihr den
"num"-Parameter angeben, ladet das Bild anschließend herunter, ladet es auf einen Imagehoster und verlinkt dieses, um diesen Server zu
entlasten.
Akzeptiert folgende Parameter (GET, zu übergeben wie "http://fichtefoll.dyndns.org/divmet/?precision=20&width=1000"):
PHP Code:
/* PARAMETERS [$_REQUEST] ****************************************************
*
* @int width Used as maximum width
* @int height Used as maximum height
* @float num Number to show, generated otherwise
* @int precision = $precision Amount of digits after the point
* @bool small [0|1] = $default_small _small images ar half-sized
* @bool unprop [0|1] = 0 Allows unproportinal resizing (no upscales though)
*
*****************************************************************************/
Beispiel:
http://fichtefoll.dyndns.org/divmet/?precision=9&num=1337.123456789&small=1
[Only registered and activated users can see links. Click Here To Register...]
Andere Standardwerte sind:
Präzision - 6
Höhe - 184 (small = 92)
Breite - 560 (small = 280)
Source
PHP Code:
<?php
/* INFO **********************************************************************
*
* ~ Divergenzmeter generator from Steins;Gate ~
*
* Requires GD for graphic operations
* Every access and the generated number is logged,
* there is also a counter that's being increased.
*
* Copyright (c) by FichteFoll, 2011-09-06
*
*****************************************************************************/
/* PARAMETERS [$_REQUEST] ****************************************************
*
* @int width Used as maximum width
* @int height Used as maximum height
* @float num Number to show, generated otherwise
* @int precision = $precision Amount of digits after the point
* @bool small [0|1] = $default_small _small images ar half-sized
* @bool unprop [0|1] = 0 Allows unproportinal resizing (no upscales though)
*
*****************************************************************************/
/* LICENCE *******************************************************************
*
* Acutally, no licence required here. You may use this as you please.
* It's also not required to name me when you use it or modify,
* though you're still allowed to.
*
*****************************************************************************/
/* CHANGELOG *****************************************************************
*
* 2011-09-06
* + Added: "num" parameter
* + Added: Decent algorhythm to generate a digit that exceeds 1
* * Fixed: unprop and resizing did not work as expected when ?height=100&unprop=1
*
* 2011-08-25
* ~ Releasable state
*
*****************************************************************************/
/* Some Notes:
*
* I don't use much error handling in this. Logging may be turned off
*
*/
$appname = 'divmet';
// some variables you might want to change
$source = 'source/';
$precision = 6;
$default_small = 0;
$log = "$appname.log";
$log_enable = true;
$counter = "$appname.counter.txt";
// Parse input from $_REQUEST
$small = !!$_REQUEST['small'] or $default_small;
$precision = is_numeric($_REQUEST['precision']) ? $_REQUEST['precision'] : $precision;
$num = is_numeric($_REQUEST['num']) ? (float) $_REQUEST['num'] : -1;
$maxwidth = is_numeric($_REQUEST['width']) ? $_REQUEST['width'] : 0;
$maxheight = is_numeric($_REQUEST['height']) ? $_REQUEST['height'] : 0;
$prop = !$_REQUEST['unprop'];
$suffix = $small ? '_small' : '';
// logging
$IP = $_SERVER['REMOTE_ADDR'] or '';
function writeLog($type, $message = null)
{
global $log, $IP, $log_enable;
if (!$log_enable) return ;
if ($message == null or strlen($type) != 1)
{
$message = $type;
$type = " ";
}
$timestamp = date("Y-m-d H:i:s");
$logstr = $type.' '.$timestamp.' '.$IP.' '.trim($message)."\n";
return file_put_contents($log, $logstr, FILE_APPEND);
}
function incCounter()
{
global $counter;
if (!$f_counter = fopen($counter, (file_exists($counter) ? 'r+' : 'w+')))
return "";
$count = (int) fgets($f_counter);
if ($count == "")
$count = 0;
rewind($f_counter);
fwrite($f_counter, ++$count);
fclose($f_counter);
}
// action starts here /////////////////////////////////////////////////////////
// calculate acutal number if not -1
if ($num == -1)
{
$num = fmt_rand(0, 1.1);
if ($num > 1)
$num = 1 + fmt_rand(0, 0.8);
}
$numstr = sprintf("%.{$precision}f", $num = round($num, $precision));
// create array for keeping opend handles
$img_array = array();
// retrieve size of point to calculate size since it's used anyway
$img_array['.'] = imagecreatefrompng("{$source}Point{$suffix}.png")
or die("Failed to determine dimensions");
$sw = imagesx($img_array['.']);
$sh = imagesy($img_array['.']);
$height = $sh;
$width = $sw * strlen($numstr);
// create output image
$img = imagecreatetruecolor($width, $height)
or die("Failed to create image");
// no transparency needed as these images are not transparent, too
//~ $trans_colour = imagecolorallocatealpha($img, 0, 0, 0, 127);
//~ imagefill($img, 0, 0, $trans_colour);
// fill output image
for ($i = 0; $i < strlen($numstr); ++$i)
{
$sub = substr($numstr, $i, 1);
if (!$img_array[$sub] and !($img_array[$sub] = imagecreatefrompng("{$source}{$sub}{$suffix}.png")))
die("failed to load image for '$sub'");
imagecopy($img, $img_array[$sub], $i * $sw, 0, 0, 0, $sw, $sh);
}
// resize (no upscale)
if ($maxwidth or $maxheight)
{
if ($newimg = imageresample($img, $maxwidth, $maxheight, $width, $height, $prop))
{
imagedestroy($img);
$img =& $newimg;
}
}
// do logging
writeLog("$numstr | " . ($newimg ? "Resized to: {$maxwidth}x{$maxheight}" : "{$width}x{$height}"));
incCounter();
// output
header("Content-type: image/png");
imagepng($img);
imagedestroy($img);
foreach ($img_array as $t_img)
imagedestroy($t_img);
// functions //////////////////////////////////////////////////////////////////
function fmt_rand($min = 0, $max = 1) // "f" for "float"
{
return $min + ($max-$min) * mt_rand()/mt_getrandmax();
}
function imageresample($image, &$width, &$height, $width_orig = 0, $height_orig = 0, $prop = true)
{
def($width_orig, imagesx($image));
def($height_orig, imagesy($image));
if (!$prop)
{
def($width, $width_orig);
def($heigth, $heigth_orig);
}
else
{
// calculate dimensions
$ratio = min($width ? $width/$width_orig : 1, $height ? $height/$height_orig : 1);
$height = (int) ($height_orig * $ratio);
$width = (int) ($width_orig * $ratio);
}
// no upscale
if ($width > $width_orig or $height > $height_orig) return null;
// create and copy image
if (!$image_out = imagecreatetruecolor($width, $height))
return null;
return imagecopyresampled($image_out, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig)
? $image_out : null;
}
function def(&$ref, $alt)
{
$ref = ($ref == 0) ? $alt : $ref or $alt;
}
?>
[Only registered and activated users can see links. Click Here To Register...]
Bilder zu finden unter
[Only registered and activated users can see links. Click Here To Register...].
Die "_small" Bilder waren eigentlich für den Anfang gedacht, als ich das Resizen noch nicht eingebaut hatte. Um das Feature abzuschalten, einfach "$suffix = $small ? '_small' : '';" mit "$suffix = '';" ersetzen.
Auch können einige Variablen am Anfang des Skripts leicht verändert werden, zum Beispiel ob eine Logdatei angelegt werden soll.
Ich habe außerdem eine index.php angelegt mit einem simplen
PHP Code:
<?php
require 'divmet.php';
?>
, damit die Hauptdatei auch ohne das "divmet.php" geladen wird.
Eine dynamische Weiterleitung mit der .htaccess a la "divmet_w100_p12.png" habe ich nicht geschafft und erscheint mir auch nicht mehr notwendig.
Ein Archiv mit allen Dateien ist im Anhang.