r74102 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r74101‎ | r74102 | r74103 >
Date:20:25, 1 October 2010
Author:neilk
Status:deferred
Tags:
Comment:
splitting into a library
Modified paths:
  • /branches/uploadwizard/extensions/UploadWizard/test/php/scripts/RandomImageGenerator.php (added) (history)

Diff [purge]

Index: branches/uploadwizard/extensions/UploadWizard/test/php/scripts/RandomImageGenerator.php
@@ -0,0 +1,181 @@
 2+<?php
 3+
 4+/*
 5+ * generateRandomImages -- does what it says on the tin.
 6+ *
 7+ * Because MediaWiki tests the uniqueness of media upload content, and filenames, it is sometimes useful to generate
 8+ * files that are guaranteed (or at least very likely) to be unique in both those ways.
 9+ * This generates a number of filenames with random names and random content (colored circles)
 10+ *
 11+ * Requires Imagick, the ImageMagick library for PHP.
 12+ *
 13+ * @file
 14+ * @author Neil Kandalgaonkar <neilk@wikimedia.org>
 15+ */
 16+
 17+$defaults = array(
 18+ 'dict' => "/usr/share/dict/words",
 19+ 'number' => 10,
 20+ 'minWidth' => 400,
 21+ 'maxWidth' => 800,
 22+ 'minHeight' => 400,
 23+ 'maxHeight' => 800,
 24+ 'format' => 'jpg'
 25+);
 26+
 27+writeRandomImages( getOptions( $defaults ) );
 28+
 29+
 30+
 31+
 32+/**
 33+ * Override defaults with command-line options
 34+ *
 35+ * @param {Array} key-value default values
 36+ * @return {Array} defaults with CLI overrides
 37+ */
 38+function getOptions( $defaults ) {
 39+
 40+ // all options are optional, so append '::' to spec
 41+ $getoptSpec = array_map( function($s) { return $s . "::"; }, array_keys( $defaults ) );
 42+ $cliOptions = getopt( null, $getoptSpec );
 43+
 44+ $options = array();
 45+ foreach ( $defaults as $key => $value ) {
 46+ $options[$key] = array_key_exists( $key, $cliOptions ) ? $cliOptions[$key] : $defaults[$key];
 47+ }
 48+
 49+ return $options;
 50+}
 51+
 52+
 53+
 54+/**
 55+ * writes random images with random files to disk in current working directory
 56+ *
 57+ * @param {Array} key-value options
 58+ */
 59+function writeRandomImages( $options ) {
 60+ global $dictionary;
 61+
 62+ // each filename uses two words from the dictionary
 63+ $wordsDesired = $options['number'] * 2;
 64+
 65+ foreach( getPairs( getRandomLines( $wordsDesired, $options['dict'] ) ) as $pair ) {
 66+ $filename = $pair[0] . '_' . $pair[1] . '.' . $options['format'];
 67+
 68+ // strip all whitespace (in case we somehow have inner whitespace)
 69+ $filename = preg_replace( '/\s+/', '', $filename );
 70+
 71+ $image = getRandomImage( $options['minWidth'], $options['maxWidth'], $options['minHeight'], $options['maxHeight'] );
 72+ $image->setImageFormat( $options['format'] );
 73+ $image->writeImage( $filename );
 74+ }
 75+}
 76+
 77+
 78+/**
 79+ * Generate an image consisting of randomly colored and sized circles
 80+ * @return {Image}
 81+ */
 82+function getRandomImage($minWidth, $maxWidth, $minHeight, $maxHeight) {
 83+ global $options;
 84+
 85+ $imageWidth = mt_rand( $minWidth, $maxWidth );
 86+ $imageHeight = mt_rand( $minHeight, $maxHeight );
 87+
 88+ $image = new Imagick();
 89+ $image->newImage( $imageWidth, $imageHeight, new ImagickPixel( getRandomColor() ) );
 90+
 91+
 92+ $diagonalLength = sqrt( pow( $imageWidth, 2 ) + pow( $imageHeight, 2 ) );
 93+
 94+ for ( $i = 0; $i <= 5; $i++ ) {
 95+ $radius = mt_rand( 0, $diagonalLength / 4 );
 96+ $originX = mt_rand( -1 * $radius, $imageWidth + $radius );
 97+ $originY = mt_rand( -1 * $radius, $imageHeight + $radius );
 98+ $perimeterX = $originX + $radius;
 99+ $perimeterY = $originY + $radius;
 100+
 101+ $draw = new ImagickDraw();
 102+ $draw->setFillColor( getRandomColor() );
 103+ $draw->circle( $originX, $originY, $perimeterX, $perimeterY );
 104+ $image->drawImage( $draw );
 105+
 106+ }
 107+
 108+ return $image;
 109+}
 110+
 111+
 112+
 113+/**
 114+ * Generate a string of random colors for ImageMagick, like "rgb(12, 37, 98)"
 115+ *
 116+ * @return {String}
 117+ */
 118+function getRandomColor() {
 119+ $components = array();
 120+ for ($i = 0; $i <= 2; $i++ ) {
 121+ $components[] = mt_rand( 0, 255 );
 122+ }
 123+ return 'rgb(' . join(', ', $components) . ')';
 124+}
 125+
 126+/**
 127+ * Turn an array into an array of pairs.
 128+ *
 129+ * @param {Array} an array
 130+ * @return {Array} of two-element arrays
 131+ */
 132+function getPairs( $arr ) {
 133+ // construct pairs of words
 134+ $pairs = array();
 135+ $count = count( $arr );
 136+ for( $i = 0; $i < $count; $i += 2 ) {
 137+ $pairs[] = array( $arr[$i], $arr[$i+1] );
 138+ }
 139+ return $pairs;
 140+}
 141+
 142+/**
 143+ * Return N random lines from a file
 144+ *
 145+ * Will die if the file could not be read or if it had fewer lines than requested.
 146+ *
 147+ * @param {Integer} number of lines desired
 148+ * @string {String} path to file
 149+ * @return {Array} of exactly n elements, drawn randomly from lines the file
 150+ */
 151+function getRandomLines( $number_desired, $filepath ) {
 152+ $lines = array();
 153+ for ( $i = 0; $i < $number_desired; $i++ ) {
 154+ $lines[] = null;
 155+ }
 156+
 157+ /*
 158+ * This algorithm obtains N random lines from a file in one single pass. It does this by replacing elements of
 159+ * a fixed-size array of lines, less and less frequently as it reads the file.
 160+ */
 161+ $fh = fopen( $filepath, "r" ) or die( "couldn't open $filepath" ) ;
 162+ $line_number = 0;
 163+ $max_index = $number_desired - 1;
 164+ while( !feof( $fh ) ) {
 165+ $line = fgets( $fh );
 166+ if ( $line !== false ) {
 167+ $line_number++;
 168+ $line = trim( $line );
 169+ if ( mt_rand( 0, $line_number ) <= $max_index ) {
 170+ $lines[ mt_rand( 0, $max_index ) ] = $line;
 171+ }
 172+ }
 173+ }
 174+ fclose( $fh );
 175+ if ( $line_number < $number_desired ) {
 176+ die( "not enough lines in $filepath" );
 177+ }
 178+
 179+ return $lines;
 180+}
 181+
 182+?>
Property changes on: branches/uploadwizard/extensions/UploadWizard/test/php/scripts/RandomImageGenerator.php
___________________________________________________________________
Added: svn:eol-style
1183 + native

Status & tagging log