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: http://git.cyclocoop.org/%22%20.%20generer_url_ecrire%28%22articles_versions%22%2C%22id_article=%24id_article%22%29%20.%20%22?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 = "" .
"
";
+ 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 = "
";
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