Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Session Logistics

Status
Not open for further replies.

DonP

IS-IT--Management
Jul 20, 2000
684
0
0
US
Maybe someone can help with the odd problem. I have a small program which gets a random image (a photo) from the database, then presents it to the screen. The script is called up as though it were am image using an img src tag.

It works fine but I am having trouble passing on the height and width values to the screen. The pairs seem to be one image behind the one being shown on the screen so, unless the same image happens to load a second time in a row, the aspect ratio is off.

Code:
	SetSession("ImageWidth", "");
	SetSession("ImageHeight", "");

$DB->query("SELECT Image, ImageFormat, ImageWidth, ImageHeight FROM images_random WHERE Image IS NOT NULL AND RandomType = 3 ORDER BY RAND() LIMIT 1", $DB);
if ($DB->next_record()) {
	$mime_type = $DB->f("ImageFormat");
	$Image = $DB->f("Image");
	SetSession("ImageWidth", $DB->f("ImageWidth"));
	SetSession("ImageHeight", $DB->f("ImageHeight"));
}

if ($DB->next_record()) {
    $Image = $DB->f("Image");
}

Header ("Content-type: image/" . $mime_type);
Header ("Pragma: no-cache");
echo $Image;
exit();


In order to try to add some slight delay for the writing of the session for the specific image being viewed, I added a second "select" but it made no difference at all.

Code:
	SetSession("ImageWidth", "");
	SetSession("ImageHeight", "");

$DB->query("SELECT ID, ImageFormat, ImageWidth, ImageHeight FROM images_random WHERE Image IS NOT NULL AND RandomType = ".$Type . " ORDER BY RAND() LIMIT 1", $DB);
if ($DB->next_record()) {
	$image_id = $DB->f("ID");
	$mime_type = $DB->f("ImageFormat");
	SetSession("ImageWidth", $DB->f("ImageWidth"));
	SetSession("ImageHeight", $DB->f("ImageHeight"));
}

$DB->query("SELECT Image FROM images_random WHERE ID = ".$image_id);

if ($DB->next_record()) {
	$Image = $DB->f("Image");
}

Header ("Content-type: image/" . $mime_type);
Header ("Pragma: no-cache");
echo $Image;
exit();

Any ideas? These two pieces of code are using a couple custom functions (one for the session values and the other for the database connections), but these work fine and are not part of the problem - at least I don't think they are because they are working.

Don
contact@pc-homepage.com
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
perhaps if I truly understand what setSession does I can help you.

if you want to put attributes of image i don't think you should put it in session? because if you put it in session it really will only be recognized in the second running of the script.


Did you try not putting out the image on the screen but instead printing the Database results to the screen and see if the width/height comes out correctly?


Regards,

Namida
 
SetSession() simply sets a session value, which in this case is the height and width values of the images being viewed. The first parameter sets the session's name while the other sets its value. The two uppermost calls to the function are supposed to set these two to null.

It is another script that has the IMG SRC tag where the script above it being run. In fact, it is called from several other pages and it is in these other scripts that I am trying to grab the values for the height and width. However, you're right that the script above is being run by being accessed using IMG SRC so that the session values for the height and width are always behind the current image.

It's a good idea that I haven't tried but I'm not sure if I can print it to the screen since the script is being accessed as though it were an image. It needs to output image header and image data.

Don
contact@pc-homepage.com
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
How are you invoking the script? If you have an <img> tag in another script invoking this one, that's where the height and width should be entered, not it this one.

Also, why are you invoking a function to set a session value? Why not use $_SESSION['index'] directly and save the cost of a function invocation.

Ken
 
Yes, the script is being invoked as though it were an image. Normally I know ahead of time which image is being accessed and can get the height and width directly on any other script that invokes it but, as this one is getting a random entry, that's impossible here.

It IS in the other script that I am using the height and width but, since the image is chosen randomly in the script above, a session was the only thing I could think of for passing on the values into the other script.

I am using a function because it is built into the IDE development platform that I use. It's easier to use it than to not. It is not the problem and works fine.

Don
contact@pc-homepage.com
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
Any particular reason for the two if statements:
Code:
if ($DB->next_record()) {
    $mime_type = $DB->f("ImageFormat");
    $Image = $DB->f("Image");
    SetSession("ImageWidth", $DB->f("ImageWidth"));
    SetSession("ImageHeight", $DB->f("ImageHeight"));
}

if ($DB->next_record()) {
    $Image = $DB->f("Image");
}
$DB->next_record() is incrementing the record it is on, try moving the image grabbing to the other if statement like so:
Code:
if ($DB->next_record()) {
    $mime_type = $DB->f("ImageFormat");
    $Image = $DB->f("Image");
    SetSession("ImageWidth", $DB->f("ImageWidth"));
    SetSession("ImageHeight", $DB->f("ImageHeight"));
    $Image = $DB->f("Image");
}
 
Oh, it was an error in my posting that I never noticed until now. The first sample should not have had:

Code:
if ($DB->next_record()) {
    $Image = $DB->f("Image");
}

which is obviously doing nothing useful.





Don
contact@pc-homepage.com
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
Ah gotcha - I just noticed $Image already being set there now too...
 
The only way to do what you want is to seperate the fetching of the random image from the display.

In your main script, you could have a function to do the fetching:
Code:
function get_random_image()
{
    SetSession("ImageWidth", "");
    SetSession("ImageHeight", "");

$DB->query("SELECT Image, ImageFormat, ImageWidth, ImageHeight FROM images_random WHERE Image IS NOT NULL AND RandomType = 3 ORDER BY RAND() LIMIT 1", $DB);
if ($DB->next_record()) {
    $mime_type = $DB->f("ImageFormat");
    SetSession("Image", $DB->f("Image"));
    SetSession("ImageWidth", $DB->f("ImageWidth"));
    SetSession("ImageHeight", $DB->f("ImageHeight"));
}
}

//
//  code ....
//
get_random_image();
echo '<img src=display_image.php width=' . $_SESSION['ImageWidth'] . ' height=' . $_SESSION['ImageHeight'] . '>';
?>

As it is now, without seeing your invoking script, you're not setting the width and height in the SESSION array until after you invoke the <img> tag. So the first time through, they are not set, so the picture probably displays correctly, the next time you invoke it the width and height get set to the width and height of the previous picture, since that's what's in the SESSION array. If they happen to be the same, your picture is display correctly, if not it will be distorted.

By setting the values in the SESSION array before invoking the <img> tag, you will get the correct values.

In your script that displays the image, make sure you get the image from the $_SESSION array.

Ken
 
I had thought of that before as a workaround but it does appear to be the only way. It seems that it would require yet another script for actually showing the image in the IMG SRC tag. Is that what you were thinking? If so, I am not sure how to call the one script to get the image from the database and set the session values, then the second one for showing it as the whole thing somehow needs to come from a single IMG SRC tag.

Another thought that just occurred to me is in using the GD libraries where the image can be stored physically as a temp file, then I seem to recall that the GD libraries had some way of getting the whole IMG SRC tag including the height and width. I'll have to research as to how to do this.

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
The GD libraries can indeed be used to size your image - however it is not "getting around" the heigh/width of the img tag.

The browser will size an image to the height/width of the img tag - however the actual size is still the size of the image on the server and upon saving the image will save the full size.

However if you size using the GD library, then the "true size" the browser sees is the size specified by the script. Thus keeping your original image one size, and the physical size sent to the browser another size.
 
The code for getting the image information from the database is a function in your main script. The code that displays the image goes in the script that is invoked via the <img> tag.

If you're going to use GD instead, you shouldn't store the image itself in the database, just the file name. Then you can get a random filename, use GD functions to get the height and width, and then generate your <img> tag.

Ken
 
Or you can keep keep you html generation the same and have the GD script called directly from your img tag:
Code:
<img src="db_image.php">

db_image.php would then get the path, and height/width and apply it and output the image like you were doing originally.

Here is an modified script that I use to create thumbnails this way:

Code:
<?php
// Load database
require("db_config.php");
$id = 1;
if(isset($_GET['id']) && !empty($_GET['id'])){
	$id = $_GET['id'];
}
$query = "SELECT Image FROM image_db WHERE (ID=" . $id . ")";
$result = mysql_query($query) or die("General Parse Error: " . $query);
while ($next = mysql_fetch_array($result, MYSQL_ASSOC)){
	$imagepath = $next["Image"];
}
header ("Content-type: image/png");  //Or whatever

list($img_width, $img_height, $type, $attr) = getimagesize($imagepath);
switch($type){
	case 1:
		if(function_exists("imagecreatefromgif")){
			$im = imagecreatefromgif($imagepath)
    			or die ("Cannot Initialize new GD image stream");
    	} else {
    		$im = imagecreate(200,50);
			$background = imagecolorallocate($im,0,0,0);
			$tc = imagecolorallocate($im,255,255,255);
			imagettftext($im,12,0,15,25,$tc,$fontfile,"GIF not supported.");
    	}
		break;
	case 2:
		if(function_exists("imagecreatefromjpeg")){
			$im = imagecreatefromjpeg($imagepath)
    			or die ("Cannot Initialize new GD image stream");
    	} else {
    		die ("Image type (jpg) not supported.");
    	}
		break;
	case 3:
		if(function_exists("imagecreatefrompng")){
			$im = imagecreatefrompng($imagepath)
    			or die ("Cannot Initialize new GD image stream");
    	} else {
    		die ("Image type (png) not supported.");
    	}
		break;
	default:
		$im = imagecreate(200,50);
		$background = imagecolorallocate($im,0,0,0);
		$tc = imagecolorallocate($im,255,255,255);
		imagettftext($im,12,0,15,25,$tc,$fontfile,"Image type not supported.");
		break;
}

//resize pic
$oW = imagesx($im);
$oH = imagesy($im);
$scale = min(150/$oW, 150/$oH); //Used for scaling the image to a min width or height of 150

if($scale < 1){
	$nW = floor($scale * $oW);  //New Width
	$nH = floor($scale * $oH);  //New Height
	
	$tmp_im = imagecreate($nW, $nH);
	
	imagecopyresized($tmp_im, $im, 0, 0, 0, 0,
		$nW, $nH, $oW, $oH);
	imagedestroy($im);
	$im = $tmp_im;
}
//Error if necessary
if(!$im){
	$im = imagecreate(150,150);
	imagecolorallocate($im,0,0,0);
	$c = imagecolorallocate($im,70,70,70);
	imageline($im,0,0,150,150,$c);
	imageline($im,150,0,0,150,$c);
}

imagepng ($im);
imagedestroy ($im);
?>
 
Thanks, I think with all this help I should be able to get it to work one way or another. As far as the images being in the database, they are there and can't be changed, unfortunately.

Wow! I just saw the last posting which looks great. I'll check it out in detail later today although in looking through it briefly, I think I can simplify it considerably for my needs. Some of the resizing would be handy, though, so that I can make the images more or less consistant at least in width. Possibly I could even add a watermark . . .

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
Yep - you could add watermarks (text or images - I haven't done images though).

That code that I posted is dependent on pulling the image path from the database, and then the image from that path. I'm not sure about using the GD on an image from a db.
 
The GD library works just as well on an image from a database as from a physical file (it's a little easier, actually) and I do it all the time. It was only the "randomness" of this particular script that had me stumped!

Thanks again for the nice example, which I think will probably do the trick.

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
No problem, glad to help.

Yea just found that out about the DB - found the imagecreatefromstring() function should do the trick.

I may have to start using that now that I know about it. :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top