From: Erik Moeller Date: Mon, 12 Jan 2004 00:55:01 +0000 (+0000) Subject: JeLuF's image resizing code X-Git-Tag: 1.3.0beta1~1165 X-Git-Url: https://git.cyclocoop.org/admin/?a=commitdiff_plain;h=99f6383f37d36b018b0c0bfb5cfa1a3f94e08c2b;p=lhc%2Fweb%2Fwiklou.git JeLuF's image resizing code --- diff --git a/LocalSettings.sample b/LocalSettings.sample index 67b1b4ed2e..758631a911 100644 --- a/LocalSettings.sample +++ b/LocalSettings.sample @@ -38,6 +38,15 @@ $wgDBsqlpassword = "sqlpass"; $wgDBminWordLen = 3; # Match this to your MySQL fulltext $wgDBtransactions = false; # Set to true if using InnoDB tables +# This is the location of the convert program +# from the ImageMagick toolbox. You need it for +# the image resizing functionality. +# +# Set $wgUseImageResize to true if you want to use this feature +# +$wgUseImageResize = false; +$wgImageMagickConvertCommand = "/usr/bin/convert"; + # Turn this on during database maintenance # $wgReadOnly = true; diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 63ad667fd7..e945a31c35 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -99,12 +99,43 @@ function wfImageUrl( $img ) return wfUrlencode( $url ); } -function wfImageArchiveUrl( $name ) +function wfImagePath( $img ) +{ + global $wgUploadDirectory; + + $nt = Title::newFromText( $img ); + if( !$nt ) return ""; + + $name = $nt->getDBkey(); + $hash = md5( $name ); + + $url = "{$wgUploadDirectory}/" . $hash{0} . "/" . + substr( $hash, 0, 2 ) . "/{$name}"; + return wfUrlencode( $url ); +} + +function wfThumbUrl( $img ) +{ + global $wgUploadPath; + + $nt = Title::newFromText( $img ); + if( !$nt ) return ""; + + $name = $nt->getDBkey(); + $hash = md5( $name ); + + $url = "{$wgUploadPath}/thumb/" . $hash{0} . "/" . + substr( $hash, 0, 2 ) . "/{$name}"; + return wfUrlencode( $url ); +} + + +function wfImageArchiveUrl( $name, $subdir="archive" ) { global $wgUploadPath; - $hash = md5( substr( $name, 15) ); - $url = "{$wgUploadPath}/archive/" . $hash{0} . "/" . + $hash = md5( $name ); + $url = "{$wgUploadPath}/{$subdir}/" . $hash{0} . "/" . substr( $hash, 0, 2 ) . "/{$name}"; return $url; } @@ -429,13 +460,13 @@ function wfImageDir( $fname ) return $dest; } -function wfImageArchiveDir( $fname ) +function wfImageArchiveDir( $fname , $subdir="archive") { global $wgUploadDirectory; $hash = md5( $fname ); $oldumask = umask(0); - $archive = "{$wgUploadDirectory}/archive"; + $archive = "{$wgUploadDirectory}/{$subdir}"; if ( ! is_dir( $archive ) ) { mkdir( $archive, 0777 ); } $archive .= "/" . $hash{0}; if ( ! is_dir( $archive ) ) { mkdir( $archive, 0777 ); } diff --git a/includes/ImagePage.php b/includes/ImagePage.php index 06f2927636..c883bf75f2 100644 --- a/includes/ImagePage.php +++ b/includes/ImagePage.php @@ -7,6 +7,10 @@ class ImagePage extends Article { function view() { + if ( Namespace::getImage() == $this->mTitle->getNamespace() ) { + $this->openShowImage(); + } + Article::view(); # If the article we've just shown is in the "Image" namespace, @@ -14,11 +18,40 @@ class ImagePage extends Article { # it describes. if ( Namespace::getImage() == $this->mTitle->getNamespace() ) { + $this->closeShowImage(); $this->imageHistory(); $this->imageLinks(); } } + + function openShowImage() + { + global $wgOut, $wgUser; + $name = $this->mTitle->getText(); + $path = wfImagePath( $name ); + $url = wfImageUrl( $name ); + + list($width, $height, $type, $attr) = getimagesize( $path ); + + $sk = $wgUser->getSkin(); + + if ( $type != "" ) { + # image + $s .= "
"; + } else { + $s .= "
".$sk->makeMediaLink($name,"")."
"; + } + $wgOut->AddHTML( $s ); + } + function closeShowImage() + { + global $wgOut, $wgUser; + $sk = $wgUser->getSkin(); + $s = ""; + $wgOut->AddHTML( $s ); + } + # If the page we've just displayed is in the "Image" namespace, # we follow it with an upload history of the image and its usage. diff --git a/includes/MagicWord.php b/includes/MagicWord.php index f0ed86d72a..c8af12b0d2 100644 --- a/includes/MagicWord.php +++ b/includes/MagicWord.php @@ -26,6 +26,7 @@ class MagicWord { $this->mRegex = ""; $this->mRegexStart = ""; $this->mVariableRegex = ""; + $this->mVariableStartToEndRegex = ""; $this->mModified = false; } @@ -59,6 +60,7 @@ class MagicWord { $this->mRegex = "/{$this->mBaseRegex}/{$case}"; $this->mRegexStart = "/^{$this->mBaseRegex}/{$case}"; $this->mVariableRegex = str_replace( "\\$1", "([A-Za-z0-9_\-]*)", $this->mRegex ); + $this->mVariableStartToEndRegex = str_replace( "\\$1", "([A-Za-z0-9_\-]*)", "/^{$this->mBaseRegex}$/{$case}" ); } # Gets a regex representing matching the word @@ -79,7 +81,7 @@ class MagicWord { } return $this->mRegexStart; } - + # regex without the slashes and what not function getBaseRegex() { @@ -100,6 +102,22 @@ class MagicWord { return preg_match( $this->getRegexStart(), $text ); } + # Returns NULL if there's no match, the value of $1 otherwise + # The return code is the matched string, if there's no variable + # part in the regex and the matched variable part ($1) if there + # is one. + function matchVariableStartToEnd( $text ) { + $matchcount = preg_match( $this->getVariableStartToEndRegex(), $text, $matches ); + if ( $matchcount == 0 ) { + return NULL; + } elseif ( count($matches) == 1 ) { + return $matches[0]; + } else { + return $matches[1]; + } + } + + # Returns true if the text matches the word, and alters the # input string, removing all instances of the word function matchAndRemove( &$text ) @@ -137,6 +155,15 @@ class MagicWord { return $this->mVariableRegex; } + # Matches the entire string, where $1 is a wildcard + function getVariableStartToEndRegex() + { + if ( $this->mVariableStartToEndRegex == "" ) { + $this->initRegex(); + } + return $this->mVariableStartToEndRegex; + } + # Accesses the synonym list directly function getSynonym( $i ) { return $this->mSynonyms[$i]; diff --git a/includes/Skin.php b/includes/Skin.php index f3a24748a3..4b1a81fc39 100644 --- a/includes/Skin.php +++ b/includes/Skin.php @@ -1421,9 +1421,77 @@ class Skin { } function makeImageLinkObj( $nt, $alt = "" ) { - $link = $nt->getPrefixedURL(); - $name = $nt->getDBKey(); - $url = wfImageUrl( $name ); + global $wgLang, $wgUseImageResize; + $link = $nt->getPrefixedURL(); + $name = $nt->getDBKey(); + $url = wfImageUrl( $name ); + $align = ""; + + if ( $wgUseImageResize ) { + # Check if the alt text is of the form "options|alt text" + # Options are: + # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang + # * left no resizing, just left align. label is used for alt= only + # * right same, but right aligned + # * none same, but not aligned + # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox + + $part = explode( "|", $alt); + + if ( count($part) > 1 ) { + $mwThumb =& MagicWord::get( MAG_IMG_THUMBNAIL ); + $mwLeft =& MagicWord::get( MAG_IMG_LEFT ); + $mwRight =& MagicWord::get( MAG_IMG_RIGHT ); + $mwNone =& MagicWord::get( MAG_IMG_NONE ); + $mwWidth =& MagicWord::get( MAG_IMG_WIDTH ); + $alt = $part[count($part)-1]; + + $thumb=false; + + foreach( $part as $key => $val ) { + if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) { + $thumb=true; + } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) { + # remember to set an alignment, don't render immediately + $align = "right"; + } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) { + # remember to set an alignment, don't render immediately + $align = "left"; + } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) { + # remember to set an alignment, don't render immediately + $align = "none"; + } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) { + # $match is the image width in pixels + $width = intval($match); + } + } + } + + if ( $thumb ) { + + # Create a thumbnail. Alignment depends on language + # writing direction, # right aligned for left-to-right- + # languages ("Western languages"), left-aligned + # for right-to-left-languages ("Semitic languages") + # + # If thumbnail width has not been provided, it is set + # here to 180 pixels + if ( $align == "" ) { + $align = $wgLang->isRTL() ? "left" : "right"; + } + if ( ! isset($width) ) { + $width = 180; + } + return $this->makeThumbLinkObj( $nt, $alt, $align, $width ); + + } elseif ( isset($width) ) { + + # Create a resized image, without the additional thumbnail + # features + $url = $this->createThumb( $name, $width ); + } + } # endif $wgUseImageResize + if ( empty( $alt ) ) { $alt = preg_replace( '/\.(.+?)^/', '', $name ); } @@ -1432,6 +1500,63 @@ class Skin { $u = wfLocalUrlE( $link ); $s = "" . "\"{$alt}\""; + if ( "" != $align ) { + $s = "
{$s}
"; + } + return $s; + } + + function createThumb( $name, $width ) { + global $wgUploadDirectory; + global $wgImageMagickConvertCommand; + $imgPath = wfImagePath( $name ); + $thumbName = $width."px-".$icon.$name; + $thumbPath = wfImageArchiveDir( $thumbName, "thumb" )."/".$thumbName; + $thumbUrl = wfImageArchiveUrl( $thumbName, "thumb" ); + + if ( (! file_exists( $thumbPath )) + || ( filemtime($thumbPath) < filemtime($imgPath) ) ) { + $cmd = $wgImageMagickConvertCommand . + " -quality 95 -geometry {$width}x ". + escapeshellarg($imgPath) . " " . + escapeshellarg($thumbPath); + $conv = shell_exec( $cmd ); + } + return $thumbUrl; + } + + function makeThumbLinkObj( $nt, $label = "", $align = "right", $boxwidth = 180 ) { + global $wgUploadPath; + $name = $nt->getDBKey(); + $image = Title::makeTitle( Namespace::getImage(), $name ); + $link = $image->getPrefixedURL(); + $url = wfImageUrl( $name ); + $path = wfImagePath( $name ); + + list($width, $height, $type, $attr) = getimagesize( $path ); + $cwidth = $boxwidth; + $cheight = intval( $height/($width/$cwidth) ); + if ($cheight > $boxwidth*1.5) { + $cheight = $boxwidth*1.3; + $cwidth = intval( $width/($height/$cheight) ); + } + if ( $cwidth > $width ) { + $cwidth = $width; + $cheight = $height; + } + + $thumbUrl = $this->createThumb( $name, $cwidth ); + + $u = wfLocalUrlE( $link ); + + $more = wfMsg( "thumbnail-more" ); + + $s = "
" . + "" . + "\"{$label}\"" . + "" . + "\"{$more}\"" . + "

{$label}

"; return $s; } diff --git a/languages/Language.php b/languages/Language.php index 9e7c1bcfce..b5a7144593 100644 --- a/languages/Language.php +++ b/languages/Language.php @@ -20,6 +20,12 @@ define("MAG_SUBST", 12); define("MAG_MSGNW", 13); define("MAG_NOEDITSECTION", 14); define("MAG_END", 15); +define("MAG_IMG_THUMBNAIL", 16); +define("MAG_IMG_RIGHT", 17); +define("MAG_IMG_LEFT", 18); +define("MAG_IMG_NONE", 19); +define("MAG_IMG_WIDTH", 20); + #-------------------------------------------------------------------------- # Language-specific text @@ -300,7 +306,13 @@ this (alternative: like this?).", MAG_MSG => array( 0, "{{MSG:$1}}" ), MAG_SUBST => array( 0, "{{SUBST:$1}}" ), MAG_MSGNW => array( 0, "{{MSGNW:$1}}" ), - MAG_END => array( 0, "__END__" ) + MAG_END => array( 0, "__END__" ), + MAG_IMG_THUMBNAIL => array( 1, "thumbnail", "thumb"), + MAG_IMG_RIGHT => array( 1, "right" ), + MAG_IMG_LEFT => array( 1, "left" ), + MAG_IMG_NONE => array( 1, "none" ), + MAG_IMG_WIDTH => array( 1, "$1px" ) + ); # All special pages have to be listed here: a description of "" @@ -1302,7 +1314,12 @@ amusement.", # Namespace 8 related "allmessages" => "All_messages", -"allmessagestext" => "This is a list of all messages available in the MediaWiki: namespace" +"allmessagestext" => "This is a list of all messages available in the MediaWiki: namespace", + +# Thumbnails + +"thumbnail-more" => "Enlarge" + ); #-------------------------------------------------------------------------- diff --git a/stylesheets/cologneblue.css b/stylesheets/cologneblue.css index 4d2c0004b9..982d0d0f4b 100644 --- a/stylesheets/cologneblue.css +++ b/stylesheets/cologneblue.css @@ -94,3 +94,43 @@ a.stub { color:#772233; text-decoration:none; } small { font-size: 75%; } #toc { border:1px solid #8888aa; background-color:#f7f8ff;padding:5px;font-size:95%; } + +/* Images */ +div.floatright { float: right; margin: 0 0 1em 1em; } +div.floatright p { font-style: italic; } +div.floatleft { float: left; margin: 0.3em 0.5em 0.5em 0; } +div.floatleft p { font-style: italic; } + + +/* thumbnails */ +div.thumbnail-none, div.thumbnail-right, div.thumbnail-left { + padding: 2px; + border:1px solid #8888aa; + background:#CCCCCC; + margin: 0.3em 0 0.5em; + font-size: 85%; +} + +div.thumbnail-none p, div.thumbnail-right p, div.thumbnail-left p { + margin-top:3px; margin-bottom:3px; +} + +div.thumbnail-right { + float: right; + margin-left:0.5em; +} + +div.thumbnail-left { + float: left; + margin-right:0.5em; +} + +/* table standards */ +table.rimage { + float:right; + width:1pt; + margin-left:1em; + margin-bottom:1em; + text-align:center; + font-size:smaller; + } diff --git a/stylesheets/nostalgia.css b/stylesheets/nostalgia.css index 231342b21f..4543ca1577 100644 --- a/stylesheets/nostalgia.css +++ b/stylesheets/nostalgia.css @@ -12,3 +12,43 @@ h2, h3, h4, h5, h6 { margin-bottom: 0; } p.subtitle { padding-top: 0; margin-top: 0; } #toc { border:1px solid #8888aa; background-color:#f7f8ff;padding:5px;font-size:95%; } + +/* Images */ +div.floatright { float: right; margin: 0 0 1em 1em; } +div.floatright p { font-style: italic; } +div.floatleft { float: left; margin: 0.3em 0.5em 0.5em 0; } +div.floatleft p { font-style: italic; } + + +/* thumbnails */ +div.thumbnail-none, div.thumbnail-right, div.thumbnail-left { + padding: 2px; + border:1px solid #8888aa; + background:#CCCCCC; + margin: 0.3em 0 0.5em; + font-size: 85%; +} + +div.thumbnail-none p, div.thumbnail-right p, div.thumbnail-left p { + margin-top:3px; margin-bottom:3px; +} + +div.thumbnail-right { + float: right; + margin-left:0.5em; +} + +div.thumbnail-left { + float: left; + margin-right:0.5em; +} + +/* table standards */ +table.rimage { + float:right; + width:1pt; + margin-left:1em; + margin-bottom:1em; + text-align:center; + font-size:smaller; + } \ No newline at end of file diff --git a/stylesheets/wikistandard.css b/stylesheets/wikistandard.css index d4e20a7130..ec6f84ef35 100644 --- a/stylesheets/wikistandard.css +++ b/stylesheets/wikistandard.css @@ -38,8 +38,35 @@ td { empty-cells:show; } td.bottom { border-top: 1px solid gray; } td.top { border-bottom: 1px solid gray; } /* images */ -div.floatright { float:right;margin:0 0 1em 1em; } +div.floatright { float: right; margin: 0 0 1em 1em; } div.floatright p { font-style: italic; } +div.floatleft { float: left; margin: 0.3em 0.5em 0.5em 0; } +div.floatleft p { font-style: italic; } + +/* thumbnails */ +div.thumbnail-none, div.thumbnail-right, div.thumbnail-left { + padding: 2px; + border:1px solid #8888aa; + background:#CCCCCC; + margin: 0.3em 0 0.5em; + font-size: 85%; + text-align: center; +} + +div.thumbnail-none p, div.thumbnail-right p, div.thumbnail-left p { + margin-top:3px; margin-bottom:3px; + text-align: left; +} + +div.thumbnail-right { + float: right; + margin-left:0.5em; +} + +div.thumbnail-left { + float: left; + margin-right:0.5em; +} /* table standards */ table.rimage { @@ -49,25 +76,4 @@ table.rimage { margin-bottom:1em; text-align:center; font-size:smaller; - } - -table.country { - border-width:1; - border-style:solid; - padding:2; - border-spacing:0; - float:right; - width:300px; - } - -table.flag { - background-color:#efefef; - border-width:0; - border-spacing:0; - padding:2; - } - -td.flag { - text-align:center; - width:140px; - } + } \ No newline at end of file