Helpful Information
 
 
Category: vBulletin.org Forum
[RELEASE vB2.0b2] Image size restriction hack

Okay, I don't know about the rest of you, but I was getting a little tired of images being WAY too huge in posts and blowing away the formatting of the tables. So, after collecting some code here and there and hacking the functions.php file we have the following hack. Please note that I'm not claiming for this to be the best code in the world, but after a couple of hours of debugging, it'll have to do -- you may optimize at will!

This hack will allow you to set the maximum width that you want an image to be and any pic in a signature or a post will be automatically sized to fit within this parameter. This does NOT resize the image graphic, but rather just figures out what the maximum "height" and "width" parameters should be on the IMG tag when displaying it. The images will still take as long to download since its the same larger graphic, but they'll be sized correctly at least.

This will only work on vBcode IMG tags!

Okay, here are the steps:

In function.php, in the bbcodeparse2() function, look for the following code:

if($dobbimagecode) {
// do [ img ]xxx[ /img ]
$bbcode = preg_replace("/(\[)(img)(])(\r\n)*([^\"]*)(\[\/img\])/siU", "<img src=\"\\5\" border=\"1\" alt=\"\">", $bbcode);
}

Replace this code with:

if($dobbimagecode) {
// do [ img ]xxx[ /img ]
$pattern = "/(\[)(img)(])(\r\n)*([^\"]*)(\[\/img\])/siU";
preg_match_all($pattern, $bbcode, $images);
$num_images = sizeof($images[5]);
for ($loop = 0; $loop < $num_images;$loop++){
$image_url[$loop] = $images[5][$loop];
$new_image_size = imagereduction($image_url[$loop]);
$new_image_width[$loop] = $new_image_size[width];
$new_image_height[$loop] = $new_image_size[height];
$replace[$loop] = "<img src=\"$image_url[$loop]\" border=\"0\" alt=\"\" width=\"$new_image_width[$loop]\" height=\"$new_image_height[$loop]\">";
eval("\$pattern = \"$image_url[$loop]\";");
$encoded_pattern[$loop] = preg_quote($pattern,"/");
$bbcode = str_replace($pattern, $replace[$loop], $bbcode);
}
}

Now, at the end of functions.php, add the following:

#################################################
## GetURLImageSize( $urlpic ) determines the
## dimensions of local/remote URL pictures.
## returns array with ( $width,$height,$type )
##
## Thanks to: Oyvind Hallsteinsen aka Gosub / ELq - gosub@elq.org
## for the original size determining code
##
## PHP Hack by Filipe Laborde-Basto Oct 21/2000
## FREELY DISTRIBUTABLE -- use at your sole discretion! :) Enjoy.
## (Not to be sold in commercial packages though, keep it free!)
## Feel free to contact me at fil@rezox.com (http://www.rezox.com)
#################################################

define(GIF_SIG, "\x47\x49\x46");
define(JPG_SIG, "\xff\xd8\xff");
define(PNG_SIG, "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a");
define(JPG_SOF0, "\xc0"); /* Start Of Frame N */
define(JPG_SOF1, "\xc1"); /* N indicates which compression process */
define(JPG_SOF2, "\xc2"); /* Only SOF0-SOF2 are now in common use */
define(JPG_SOF3, "\xc3");
define(JPG_SOF5, "\xc5"); /* NB: codes C4 and CC are NOT SOF markers */
define(JPG_SOF6, "\xc6");
define(JPG_SOF7, "\xc7");
define(JPG_SOF9, "\xc9");
define(JPG_SOF10, "\xca");
define(JPG_SOF11, "\xcb");
define(JPG_SOF13, "\xcd");
define(JPG_SOF14, "\xce");
define(JPG_SOF15, "\xcf");
define(JPG_EOI, "\xd9"); /* End Of Image (end of datastream) */
define(JPG_SOS, "\xda"); /* Start Of Scan - image data start */
define(RD_BUF, 512); /* amount of data to initially read */

function GetURLImageSize( $urlpic ){
$fd= @fopen($urlpic,"r");
if($fd){
#read in 1k, enough for GIF,PNG.
#continue to read from file, if the JPG chunk exceeds this
$imgData = fread( $fd,RD_BUF );

if( substr($imgData,0,3)==GIF_SIG ){
$dim =unpack ("v2dim",substr($imgData,6,4) );
$width=$dim["dim1"]; $height=$dim["dim2"];
$type = 1;
} elseif( substr($imgData,0,8)==PNG_SIG ){
$dim =unpack ("N2dim",substr($imgData,16,8) );
$width=$dim["dim1"]; $height=$dim["dim2"];
$type = 3;
} elseif( substr($imgData,0,3)==JPG_SIG ){
################# JPG CHUNK SCAN ####################
$imgPos = 2; $type = 2; $buffer = RD_BUF-2;
while($imgPos < strlen($imgData)) {
/* synchronize to the marker 0xFF */
$imgPos=strpos(&$imgData,0xFF,$imgPos)+1;
$marker = $imgData[$imgPos];
do { $marker = ord($imgData[$imgPos++]); } while ($marker == 255);
/* find dimensions of block */
switch (chr($marker)) {
/* Grab width/height from SOF segment (these are acceptable chunk types) */
case JPG_SOF0: case JPG_SOF1: case JPG_SOF2:
case JPG_SOF3: case JPG_SOF5: case JPG_SOF6:
case JPG_SOF7: case JPG_SOF9: case JPG_SOF10:
case JPG_SOF11: case JPG_SOF12: case JPG_SOF13:
case JPG_SOF14: case JPG_SOF15:
$dim =unpack ("n2dim",substr($imgData,$imgPos+3,4) );
$height=$dim["dim1"]; $width=$dim["dim2"];
break 2; //found it so exit
case JPG_EOI:
case JPG_SOS:
return FALSE; /* End loop in case we find one of these markers */
default: /* We're not interested in other markers */
$skiplen = (ord($imgData[$imgPos++])<<8)+ord($imgData[$imgPos++])-2;
/* if the skip is more than what we've read in, read more */
$buffer -= $skiplen;
if( $buffer<512 ){ #if the buffer of data is too low,read more file.
$imgData .= fread( $fd,$skiplen+1024 );
$buffer += $skiplen+1024;
};
$imgPos += $skiplen;
break;
}; //endif check marker type
}; //endif loop through JPG chunks
}; //endif chk for valid file types

# got the pic dimensions, close the file
fclose ($fd);

return array( $width,$height,$type );
} else {
return array( '','','' );
}; //endif valid file pointer chk
}; // end function

// ###################### Start imagereduction #######################
function imagereduction($imagepath) {
// Returns an associative array with height and width attributes of
// Of a resized image.
// picsize variable control the maximum size of the height/width
// Function keeps proportions the same
$picsize = 320;

$size = GetURLImageSize($imagepath);
$dim[height] = $size[1];
$dim[width] = $size[0];

while($dim[width] > $picsize){
$dim[width] = $dim[width] * .75;
$widthreduce++; }
for($heightreduce = 0; $heightreduce < $widthreduce; $heightreduce++){
$dim[height] = $dim[height] * .75;}
while($dim[height] > $picsize){
$dim[height] = $dim[height] * .75;
$heightreduce++; }
for($widthreduce=$widthreduce; $widthreduce < $heightreduce; $widthreduce++){
$dim[width] = $dim[width] * .75;}

$dim[height] = (int)$dim[height]; $dim[width] = (int)$dim[width];

return $dim;
}


Note that in the function called imagereduction(), there is a setting for the "picsize". That should actually be the maximum width that you want for your pictures to be. The point of the imagereduction() function is to determine the proportions correctly based on the image's size.

Also note that both of these functions are someone else's and the GetURLImage() function will not be necessary with PHP 4.0.5 comes out because the PHP GetImageSize() function will accept URLs.

What I'd like is something that will also check the file size, and if it is over a set limit, it will display a link to the image rather than the image itself. This could be used in conjunction with the above hack. First the image is checked for file size; if it is too big, it is made into a link. If the file size is OK, then its width is checked and processed by the above hack.

Something I'll add about this hack is that it DOES slow down page loads a little since it's basically requesting each image once before the page is even loaded. Graphic-intensive pages could take a little longer.

JJR512: The hack you mentioned is an easy one, however, it has the same speed effect I'm mentioning here -- it requests the file once via HTTP, figures out its size, and then does something with it. If you're willing to take a little bit of a response decrease, I'll be glad to send you the code.

Yeah, please send it, and I'll see what kind of an effect it does have.










privacy (GDPR)