Archief - php: thumbnail class check

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

DeFlup

Legacy Member
'k had al eens een thumbnail generator gemaakt, maar niet in een class. En met dat'k in de week is een tutorial over classes had bekeken heb 'k beslist om der een class van te maken. Wat ik van jullie vraag is of je mn class eens wilt bekijken en me eventueel kan zeggen wat ik moet verbeteren of wat ik kan toevoegen.
PHP:
<?
/* 	Thumbnail Class
	Created by Flupke <[email protected]>
	Usage:
	** Create new thumbnail
	$thumb = new thumbnail();
	
	** Setting the file that has to be resized
	$thumb->set_original_file("image.jpg");
	
	** Setting the size
	$thumb->set_size(400,200);
	
	** Setting the size (if you use this the class will determine wether it will use the parameter for the height or the width, that 
	depends on the size of the image
	$thumb->set_autosize(200);
	
	** Setting the quality (1-100)
	Setting the quality can be used to change the filesize of the thumbnail.
	$thumb->set_quality(75);
	
	** Setting the output file
	$thumb->set_output_file("thumb_image.jpg");
	
	** Save the thumbnail
	$thumb->save_thumbnail();
*/

define('THUMBNAIL_STANDARD_QUALITY', 75);

class thumbnail {
	var $img;	
	function set_original_file ($filename) {
		// Check if file exists
		if ( !file_exists($filename) ) {
			echo "<b>[Error]</b>: File was not found";
			exit();
		}
		// Lookup imagefile extension
		$this->img['format']= strtoupper(ereg_replace(".*\.(.*)$","\\1",$filename));
		// Opening a new file
		switch ( $this->img['format'] ) {
			case "JPEG":
			case "JPG": {
				$this->img['src'] = imagecreatefromjpeg($filename);
				break;
			}
			case "PNG": {
				$this->img['src'] = imagecreatefrompng($filename);
				break;
			}
			case "GIF": {
				$this->img['src'] = imagecreatefromgif($filename);
				break;
			}
			case "WMBP": {
				$this->img['src'] = imagecreatefromwmbp($filename);
				break;
			}
			default: {
				echo "<b>[Error]</b>: Unsupported extension";
				exit();
			}
		}
		
		// Lookup image size
		list($this->img['width'], $this->img['height'], $this->img['type'], $this->img['attr']) = getimagesize($filename);
	}
	
	function set_quality ($quality) {
		// Set quality
		if ( $quality < 100 || $quality <= 1 ) $quality = THUMBNAIL_STANDARD_QUALITY;
		$this->img['quality'] = $quality;
	}
	
	function set_size ($width, $height) {
		// Check if the sizes are proper values
		if ( $width <= 0 || $width == '' || $height <= 0 || $height == '' ) {
			echo "<b>[Error]</b>: You didn't specify a proper width or height";
			exit();
		}
		else {
			$this->img['new_width'] = $width;
			$this->img['new_height'] = $height;
			// Disable autosize
			$this->img['autosize'] = '';
		}
	}
	
	function set_autosize($size) {
		// Checking size
		if ( $size <= 0 || $size == "" ) {
			echo "<b>[Error]</b>: You didn't specify a proper size";
			exit();
		}
		else {
			$this->img['autosize'] = $size;
			// Disable own size
			$this->img['new_width'] = '';
			$this->img['new_height'] = '';
		}
	}
	
	function set_output_file ($filename) {

		// Lookup imagefile extension
		$this->img['new_format']= strtoupper(ereg_replace(".*\.(.*)$","\\1",$filename));
		// Opening a new file
		switch ( $this->img['new_format'] ) {
			case "JPG":
			case "JPEG":
			case "PNG":
			case "GIF":
			case "WMBP":
				break;
			default: {
				echo "<b>[Error]</b>: Unsupported extension";
				exit();
			}
		}
		// Setting output file
		$this->img['dest_file'] = $filename;
	}
	
	function save () {
		// Checking the sizes
		if ( $this->img['new_width'] == '' && $this->img['new_height'] == '' && $this->img['autosize'] == '' ) {
			echo "<b>[Error]</b>: You forgot to specify the size of the thumbnail";
			exit();
		}
		// Checking input file
		elseif ( $this->img['format'] == '' ) {
			echo "<b>[Error]/b>: You forgot to specify an input filename";
			exit();
		}
		// Checking output file
		elseif ( $this->img['new_format'] == '' ) {
			echo "<b>[Error]/b>: You forgot to specify an output filename";
			exit();
		}
		else {
			// Determine size
			if ( $this->img['autosize'] != '' ) {
				if ( $this->img['width'] >= $this->img['height'] ) {
					$this->img['thumb_width'] = $this->img['autosize'];
					$this->img['thumb_height'] = ($this->img['autosize']/$this->img['width'])*$this->img['height'];
				}
				else {
					$this->img['thumb_height'] = $this->img['autosize'];
					$this->img['thumb_width'] = ($this->img['autosize']/$this->img['height'])*$this->img['width'];
				}
			}
			else {
				$this->img['thumb_height'] = $this->img['new_height'];
				$this->img['thumb_width'] = $this->img['new_width'];
			}
			// Create empty image
			$this->img['thumb'] = imageCreateTrueColor($this->img['thumb_width'],$this->img['thumb_height']);
			// Copy image
			imagecopyresampled($this->img['thumb'],$this->img['src'], 0, 0, 0, 0, $this->img['thumb_width'], $this->img['thumb_height'], $this->img['width'], $this->img['height']);
			// Save image
			switch ($this->img['new_format']) {
				case "JPG":
				case "JPEG": {
					if ( $this->img['quality'] == '' ) $this->img['quality'] = THUMBNAIL_STANDARD_QUALITY;
					imagejpeg($this->img['thumb'], $this->img['dest_file'], $this->img['quality']);
					break;
				}
				case "GIF": {
					imagegif($this->img['thumb'], $this->img['dest_file']); 
					break;
				}
				case "PNG": {
					imagepng($this->img['thumb'], $this->img['dest_file']);
					break;
				}
				case "WBMP": {
					imagewbmp($this->img['thumb'], $this->img['dest_file']);
					break;
				}
			}
			// End image
			imagedestroy($this->img['thumb']);			
		}
	}
}

$test = new thumbnail();
$test->set_original_file("images/dSC00616.jpg");
$test->set_output_file("images/thumb_dSC006161.jpg");
$test->set_autosize(300);
$test->set_quality(75);
$test->save();

?>

Je kan de code ook hier bekijken Link

dank bij voorbaat :)

DeFlup

Legacy Member
## Geplande updates ##
  • Blijkbaar is mijn manier voor het bepalen van het filetype niet echt ideaal, ga'k dus moeten aanpassen dat hij zijn filetype uit de getimagesize info haalt (thx to killgore @ #telenet.webdesign)

killgore

Legacy Member
ziet er goed en zeer basic uit.

Je zou nog wat meer kunnen doen voor fout-afhandeling, ik werk voor (kleinere, simpele) klasses als volgt:

een array (strings) die de laatste fouten bijhouden, bv:

$error[] = "foute extensie";

Mijn aangeroepen functie laat ik dan false retourneren :). Dan kan de gebruiker als ie wilt de laatste fout oproepen via get_last_error($echo=false); of alle fouten via get_errors($separator="<br />",$echo=false)

Voor uitgebreidere klasses kan je de trigger_error en user_error functies van php eens bekijken (en andere verwante error functies). http://www.php.net/manual/en/ref.errorfunc.php

Voor de rest ziet het er meestal goed uit, ik heb wel niet te veel naar je gd-code gekeken (meer je klasse systeem bekeken).

Ik persoonlijk zou nooit een klasse gebruiken voor wat jij hier doet maar alles in 1 functie proberen verwerken, maar als je alternatieve resize methoden gebruikt (die te vinden zijn in de comments op php.net bv.) kan een klasse wel een goede uitweg bieden.
Als laatste: bekijk ook eens het php5 object model. En maak goed gebruik van interne en externe functies (hoewel dat hier niet minder nodig is). Je kan bv. externe functies de naam save() of display() geven en de interne dan tc_CreateThumb(). tc staat voor thumbnailcreator en is een aanduiding dat de functie niet behoort van buitenaf aangeroepen te worden.

edit: je controle op het type is wel relatief goed, maar getimagesize levert (imho) 'betrouwbaarder' informatie, en levert meer dan genoeg types om te checken:
Index 2 is a flag indicating the type of the image: 1 = GIF, 2 = JPG, 3 = PNG, 4 = SWF, 5 = PSD, 6 = BMP, 7 = TIFF(intel byte order), 8 = TIFF(motorola byte order), 9 = JPC, 10 = JP2, 11 = JPX, 12 = JB2, 13 = SWC, 14 = IFF, 15 = WBMP, 16 = XBM

DeFlup

Legacy Member
## Geplande updates ##
  • Blijkbaar is mijn manier voor het bepalen van het filetype niet echt ideaal, ga'k dus moeten aanpassen dat hij zijn filetype uit de getimagesize info haalt (killgore@#telenet.webdesign) [Done]
  • Betere error handling (killgore) [Done]
  • Extra extensie's toevoegen: pcx en tiff (Tyfius)

DarkBone

Legacy Member
Opmerking geldt vooral voor PHP5:
Ik zou toch het afbeelden van fouten niet rechtstreeks in mijn klasse steken hoor. Zorg daarom voor een beter error afhandeling. Werk met try and catch (zoals het hoort binnen een OO omgeving) en deligeer binnen je klasse alle foutmelding af naar een hoger niveau (expliciet foutmelding throwen).

PHP:
if ( !file_exists($filename) ) { 
    throw new Exception('File not found!', 1);
    exit(); 
}

...

default: { 
    throw new Exception('Unsupported extension!', 1);
    exit(); 
}

Zo kun je dan in je 'driver' code dit doen:

PHP:
try
{
     set_original_file("test.jpg");
}
catch (Exception $e)
{
     echo $e->getMessage()
}

Eventueel maak je zelf je Exception class maar dat lijkt me te ver gaan.

dJeez

Legacy Member
Ik zie direct een bug (maar als je via getimagesize gaat werken zal die er snel uit zijn), je gebruikt in 't begin WMBP, terwijl 't uiteraard WBMP moet zijn, èn de extensie van dergelijke bestanden is uiteraard .bmp, niet .wbmp (ttz, die laatste zou eventueel ook nog kunnen maar ben 'k nog nooit tegengekomen) :p. Het is idd veel veiliger om een binaire controle (adhv de fileheader) te doen zoals in de getimagesize functie zit ingebakken ipv te vertrouwen op de extensie...

Wat foutafhandeling betreft : in PHP4 zou je eventueel nog kunnen werken via trigger_error (als je tevoren een functie als error handler hebt opgegeven), alleen stopt het script dan wel NIET met de verdere verwerking als er een fout is opgetreden (maw, je moet ZELF het script gaan afbreken als je dat wil).

Een mogelijke extra uitbreiding is dat je voorziet dat je op verschillende manieren de thumbnail kan genereren. Nu doe je dit via GD, maar het zou mooi zijn moest je dit ook via ImageMagick/NetPBM kunnen doen (via exec van het betreffende commando). Ik maak m'n thumbnails als GD2 niet beschikbaar is (wat al eens het geval durft te zijn bij de belgische hosting providers) altijd met ImageMagick (die dan weer wel vrij courant beschikbaar is).

DeFlup

Legacy Member
DeFlup zei:
en wat bedoel je exact met mn 'driver' code?
nvm that question :) heb is nen tutorial gezocht over dien throw en catch :)

en 'k zal wel is wat onderzoek doen naar andere manieren om thumbnails te creëren. want 'k geef toe dat deze class nog redelijk eenvoudig is, maar jah, je moet ergens beginnen hé :)

DeFlup

Legacy Member
## Geplande updates ##
  • Blijkbaar is mijn manier voor het bepalen van het filetype niet echt ideaal, ga'k dus moeten aanpassen dat hij zijn filetype uit de getimagesize info haalt (killgore@#telenet.webdesign) [Done]
  • Betere error handling (killgore)[Done]
  • Extra extensie's toevoegen: pcx en tiff (Tyfius) [Uitgesteld]
  • error handling dmv throw-catch (DarkBone) [Done]
  • alternatieve manieren voor gd resize (dJeez)

Updated Script:
PHP:
<?
/*     Thumbnail Class
    Created by Flupke <[email protected]>
    Usage:
    ** Create new thumbnail
    $thumb = new thumbnail();
    
    ** Setting the file that has to be resized
    $thumb->set_original_file("image.jpg");
    
    ** Setting the size
    $thumb->set_size(400,200);
    
    ** Setting the size (if you use this the class will determine wether it will use the parameter for the height or the width, that
    depends on the size of the image
    $thumb->set_autosize(200);
    
    ** Setting the quality (1-100)
    Setting the quality can be used to change the filesize of the thumbnail.
    $thumb->set_quality(75);
    
    ** Setting the output file
    $thumb->set_output_file("thumb_image.jpg");
    
    ** Save the thumbnail
    $thumb->save_thumbnail();
*/

define('THUMBNAIL_STANDARD_QUALITY', 75);

class thumbnail {
    var $img;
	var $error;
    function set_original_file ($filename) {
        // Lookup image size
        list($this->img['width'], $this->img['height'], $this->img['format'], $this->img['attr']) = getimagesize($filename);
        // Opening a new file
		$this->img['filename'] = $filename;
		if ( isset($this->img['format']) ) {
			switch ( $this->img['format'] ) {
				case 1:
					$this->img['src'] = imagecreatefromgif($filename);
					break;
				case 2: 
					$this->img['src'] = imagecreatefromjpeg($filename);
					break;
				case 3:
					$this->img['src'] = imagecreatefrompng($filename);
					break;
				default:
					throw new Exception('Unsupported extension!', 1);
			}
		}
    }
    
    function set_quality ($quality) {
        // Set quality
        if ( $quality < 100 || $quality <= 1 ) $quality = THUMBNAIL_STANDARD_QUALITY;
        $this->img['quality'] = $quality;
    }
    
    function set_size ($width, $height) {
        // Check if the sizes are proper values
        if ( $width <= 0 || !isset($width) || $height <= 0 || !isset($height) )
            throw new Exception('You didn\'t specify a proper width or height', 1);
        else {
            $this->img['new_width'] = $width;
            $this->img['new_height'] = $height;
            // Disable autosize
            $this->img['autosize'] = '';
        }
    }
    
    function set_autosize($size) {
        // Checking size
        if ( $size <= 0 || !isset($size) )
            throw new Exception('You didn\'t specify a proper size', 1);
        else {
            $this->img['autosize'] = $size;
            // Disable own size
            $this->img['new_width'] = '';
            $this->img['new_height'] = '';
        }
    }
    
    function set_output_file ($filename) {

        // Lookup imagefile extension
        $this->img['new_format']= strtoupper(ereg_replace(".*\.(.*)$","\\1",$filename));
        // Opening a new file
        switch ( $this->img['new_format'] ) {
            case "JPG":
            case "JPEG":
            case "PNG":
            case "GIF":
                break;
            default:
                throw new Exception('Unsupported extension', 1);
        }
        // Setting output file
        $this->img['dest_file'] = $filename;
    }
    
    function save () {
		// Checking input file
		if ( !file_exists($this->img['filename']) )
			throw new Exception("Input File (".$this->img['filename'].") was not found", 1);
        // Checking the sizes
        if ( !isset($this->img['new_width']) && !isset($this->img['new_height']) && !isset($this->img['autosize']) )
            throw new Exception('You forgot to specify the size of the thumbnail', 1);
        // Checking output file
        if ( !isset($this->img['new_format']) )
            throw new Exception('You forgot to specify an output filename', 1);
		if ( count($this->error) > 0 ) {
			return false;
		}
        else {
            // Determine size
            if ( isset($this->img['autosize']) ) {
                if ( $this->img['width'] >= $this->img['height'] ) {
                    $this->img['thumb_width'] = $this->img['autosize'];
                    $this->img['thumb_height'] = ($this->img['autosize']/$this->img['width'])*$this->img['height'];
                }
                else {
                    $this->img['thumb_height'] = $this->img['autosize'];
                    $this->img['thumb_width'] = ($this->img['autosize']/$this->img['height'])*$this->img['width'];
                }
            }
            else {
                $this->img['thumb_height'] = $this->img['new_height'];
                $this->img['thumb_width'] = $this->img['new_width'];
            }
            // Create empty image
            $this->img['thumb'] = imageCreateTrueColor($this->img['thumb_width'],$this->img['thumb_height']);
            // Copy image
            imagecopyresampled($this->img['thumb'],$this->img['src'], 0, 0, 0, 0, $this->img['thumb_width'], $this->img['thumb_height'], $this->img['width'], $this->img['height']);
            // Save image
            switch ($this->img['new_format']) {
                case "JPG":
                case "JPEG": {
                    if ( $this->img['quality'] == '' ) $this->img['quality'] = THUMBNAIL_STANDARD_QUALITY;
                    imagejpeg($this->img['thumb'], $this->img['dest_file'], $this->img['quality']);
                    break;
                }
                case "GIF": {
                    imagegif($this->img['thumb'], $this->img['dest_file']); 
                    break;
                }
                case "PNG": {
                    imagepng($this->img['thumb'], $this->img['dest_file']);
                    break;
                }
            }
            // End image
            imagedestroy($this->img['thumb']);            
        }
    }
}
try
{
	$test = new thumbnail();
	$test->set_original_file("images/dSC00616.jpg");
	$test->set_output_file("images/thumb_dSC006161.jpg");
	$test->set_autosize(300);
	$test->set_quality(75);
	$test->save();
}
catch (Exception $e)
{
     echo "<b>[Error]</b>: ".$e->getMessage();
	 exit();
}
?>

DarkBone

Legacy Member
@DeFlup

Ik zie dat ik in mijn voorbeeld een tweede argument opgaf bij het opwerpen van een fout:

Code:
throw new Exception('Unsupported extension!', 1);

Je mag dit gerust weglaten, da's erin geslopen omwille van copy/paste hier.

Code:
throw new Exception('Unsupported extension!');

Opgeven van een error_number lijkt me overbodig.
En met 'driver' code bedoelde ik inderdaad dus gewoon de 'normale' code die gebruik maakt van je klasses.

Enneuh misschien nog wat extra functionaliteit die je kunt toevoegen:
- opgeven locatie thumbnails
- opgeven prefix van thumbnails

DeFlup

Legacy Member
DarkBone zei:
@DeFlup

Enneuh misschien nog wat extra functionaliteit die je kunt toevoegen:
- opgeven locatie thumbnails
- opgeven prefix van thumbnails

mja, als je een output file geeft heeft hij de locatie al.
Maar ik denk dat je bedoelt dat als je een prefix meegeeft, dat hij de naam van de thumbnail automatisch kiest? bijv file.jpg wordt dan thumb_file.jpg ?

DeFlup

Legacy Member
dJeez, weet je soms uitleg staan voor de installatie van die imagick op een apache server op win2k systeem? want vind het alleen voor linux.

DarkBone

Legacy Member
Opgeven van locatie zou dan inderdaad wel vervallen.

Zo hoe je maar 1 maal een locatie en prefix op te geven en kun je een hele hoop images gaan verwerken. Nu zou je telkens per image de outputfile nog eens moeten opgeven. Wat een stuk omslachtiger is.

DeFlup

Legacy Member
DarkBone zei:
Opgeven van locatie zou dan inderdaad wel vervallen.

Zo hoe je maar 1 maal een locatie en prefix op te geven en kun je een hele hoop images gaan verwerken. Nu zou je telkens per image de outputfile nog eens moeten opgeven. Wat een stuk omslachtiger is.

daar hebde wel gelijk in. 'k ga is keer nadenken over systeem om verschillende files ineens in te laden zodanig dat ge maar 1 keer die save() moet doen en dat hij die dan allemaal opslaat

*edit*
denk dat 'k dit het best kan benaderen door al die ingegeven filenames in een extra array te zetten, of gewoon img['filename'] uitbreiden met meerdere kollomen

killgore

Legacy Member
nu, tbh, ik heb exception-catching niet vermeld, om enkele redenen:
-php5 only
-nog niet veel mensen zijn ermee vertrouwd
-Veel mensen zijn gewoon functie calls te doen (kijk naar mysql_error() ) voor een fout, of checken op fouten met if(!voer_uit()).

Niet dat deze methode slecht is, verre van (ik schrijf zelf men routines zo in php5 && c++), maar ik zou toch nog even wachten met ze te implenteren of zeker een alternatief voorzien.

Dus: Maak 2 klasses, 1 voor het gebruik (php4, met 'oude' error afhandeling) en 1 in PHP5 (exceptions+zie hieronder :p), je zal dubbel zo tevreden zijn later ;), want als php5 ingeburgerd geraakt zal je zowel je klasses al hebben als deftig het php5 oop model kunnen gebruiken.
Het lijkt omslachtig, maar veel meer kunnen we niet doen, er zijn nl. nog zoveel hosts zonder php5 en nog meer scripters die geen php5 kennen :), maar je moet altijd klaar staan voor de toekomst. schrijf je scripts niet voor nu maar voor zolang mogelijk.

Andere opmerking:
Als je toch in php5 bezig bent, werk dan goed he ;):
-private vars (al dan niet met implentatie van __get en __set methoden)
-functie toegang wijzigen (private protected public)
-constructor/destructor
-alle andere php5 snufjes die je denkt nodig te hebben.

edit: @djeez: trigger_error is zowat de simpelste (ma imho ook lelijkste) manier om fouten weer te geven, je moet zelf geen functie creëren (hij gebruikt de php functie die voor de niet-user errors worden gebruikt), krijgt auto lijn nr. en script en kan WEL het script laten stoppen (naargelang de E_USER_* id). Dit is dus redelijk handelijk voor het debuggen, wil je daarentegen runtime-catching, dan moet je ffcourse naar andere methoden gaan (zoals set_error_handler, eigen Error klasse/functie, exceptions)

DeFlup

Legacy Member
killgore zei:
Als je toch in php5 bezig bent, werk dan goed he ;):
-private vars (al dan niet met implentatie van __get en __set methoden)
-functie toegang wijzigen (private protected public)
-constructor/destructor
-alle andere php5 snufjes die je denkt nodig te hebben.

'k weet het, zou mij eens wat moeten verdiepen in de nieuwigheden van php5 :)
maar ben al blij dat'k het concept van classes al een beetje onder de knie heb.

BertG

Legacy Member
ik zie dat je met een globale variabele (over je hele coe) werkt:
'THUMBNAIL_STANDARD_QUALITY'

en ik heb geleerd deze NOOIT te gebruiken, tenzij het echt nodig is.
en hier zie ik het nut niet.

als je in je class meteen een globale variabele (binnen je class) definieerd met waarde 75, dan kan je deze gebruiken, en alter veranderen met je functie set_quality.

zoiets dus...
PHP:
class thumbnail {
    var $img = array ( 'quality' => 75 );

    /*wat code */

    function set_quality ($quality) {
        // Set quality
        /*controleer $quality eventueel*/
        $this->img['quality'] = $quality;
    } 

    /*wat code*/

}

DeFlup

Legacy Member
## Geplande updates ##
  • Blijkbaar is mijn manier voor het bepalen van het filetype niet echt ideaal, ga'k dus moeten aanpassen dat hij zijn filetype uit de getimagesize info haalt (killgore@#telenet.webdesign) [Done]
  • Betere error handling (killgore)[Done]
  • Extra extensie's toevoegen: pcx en tiff (Tyfius) [Uitgesteld]
  • error handling dmv throw-catch (DarkBone) [Done]
  • alternatieve manieren voor gd resize (dJeez) [Looking for info]
  • globale variable wegwerken (BertG) [DONE]

killgore

Legacy Member
kuch, dat is GEEN globale variabele, maar een constante (hier in het type identifier). Dit mag natuurlijk wel gebruikt worden en wordt in verscheidene API's gebruikt.

BertG

Legacy Member
killgore zei:
kuch, dat is GEEN globale variabele, maar een constante (hier in het type identifier). Dit mag natuurlijk wel gebruikt worden en wordt in verscheidene API's gebruikt.

excuses voor mijn slechte benoeming van de zaken (doe da vaak :) )
maar hier zie ik het nut niet van een constante.
De waarden word enkel gebruikt binnen de class, dus zou hij ook slechts binnen die class gebruikt moeten worden....
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan