I'v searched all day for a function to resize my pictures on the server on the fly, without saving them.The code works, it shows the full size images, now I want to make them smaller.
This is the function:
function resize_image($file, $width, $height) {
if (file_exists($file)){
$image = imagecreatefromjpeg($file);
list($orig_width, $orig_height) = getimagesize($file);
$ratio = $orig_width / $orig_height;
if ($ratio < 1) {
$width = $height * $ratio;
} else {
$height = $width / $ratio;
}
$new_image = imagecreatetruecolor($width, $height);
imagecopyresized($new_image, $image,
0, 0, 0, 0,
$width, $height,
$orig_width, $orig_height);
// header('Content-type: image/jpeg');
imagejpeg($new_image, NULL, 80);
}
}
From what I searched today I need to put the header (Content-type: image/jpeg') for the browser to recognize the output as an image but if I do that it stops the script.
This is the page using it:
<? include('resize.php');
$chapter='test';
$query=$db->prepare("SELECT * FROM `test_db` WHERE `test_db`.`Chapter` LIKE :? ORDER BY `id` ASC LIMIT 0, 6");
$query->bindValue(1, $chapter, PDO::PARAM_STR);
$query->execute();
$rows= $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row){
echo "<li><h2>".$row['Name']."</h2></li>" ;
resize_image("_images/".$row['img_number'].".jpg", 300, 190);
};
?>
You cannot output html and images to the browser in the same script.
You should either:
use a separate script to output the image and call that from the html like (simple example):
<img src="your_script.php?id=XX&size_x=XX&size_y=XX">
save the images to a file and link to that file from your html.
You could also encode the images as base64 strings and use that in your image tags but that would lead to a very large html file unless you are talking about simple buttons.
Don't put your closing tag in PHP. It will output whitespace after the closing tag which will alter the result.
Since when are headers stopping the script?
And yes, the reason why resized files are saved, is (1) you'll probably need them again, (2) the content type makes them an image in stead of text. If you want to resize those 'inline' you'll need two content types, and I guess that won't work that well...
What you could do, is resize and save the file, serve it and delete it. Like a temporary image file. A more direct way doesn't exist, according to me. But if I'm wrong, please point that out in the comments for me. I like to learn new stuff ;)
Edit: okay, EXCEPT when the script only handles the image resizing. Just thinking about that one right now. Sorry :)
Related
I have two images. I need to place one png image with some transparent layers on a jpeg.
This code SAVES the image in the dir as "merged.png" instead of showing it -
<?php
header("Content-Type: image/png");
$width = 200;
$height = 200;
$base_image = imagecreatefromjpeg("image.jpg");
$top_image = imagecreatefrompng("miod.png");
$merged_image = "merged.png";
imagesavealpha($top_image, true);
imagealphablending($top_image, true);
imagecopy($base_image, $top_image, 100, 100, 100, 100, $width, $height);
imagepng($base_image, $merged_image);
?>
-How do I display it on the page itself?
imagepng has two main modes of operation. With a single parameter, it outputs the file directly, so it'll show up in the browser. With two parameters, as you have, it wills save the image from the first parameter into the file given in the second parameter.
So -- just drop your second parameter, and things should work fine:
imagepng($base_image);
I am a student taking a php course and I have been assigned to create a function that creates a square based on a given set of parameters and prints it, but I must use an include statement to print all of the squares.
My Function looks like this :
function squareFunction ($size, $r, $g, $b, $backR, $backG, $backB, $posX, $posY, $length, $height) {
//create an empty image background
$imgur = imagecreatetruecolor($size, $size) or die('Cannot initialize new GD image stream');
//define the foreground and background colour
$fgcolour = imagecolorallocate($imgur, $r, $g, $b);
$bgcolour = imagecolorallocate($imgur, $backR, $backG, $backB);
//fill the image with the background colour
imagefill($imgur, 0, 0, $bgcolour);
//draw the rectangle using coordinates defined by the functions paramters
imagefilledrectangle($imgur, $posX, $posY, ($posX + $length), ($posY - $height), $fgcolour);
//output the header to tell browser this is a png
header ('Content-type: image/png');
//Write the image to be a png out
imagepng($imgur);
imagedestroy($imgur);
}
and is inside of a file called square.php
However when I try to use include "square.php"; in a seperate php file for example:
<?php
include '../../../square.php';
echo squareFunction(400,0,0,0,100,100,100,0,50,50,50);
?>
I just get a broken image link.
I then tried to include a function call at the top of my square.php file, but then when I used the include statement it would just print the square as soon as the include was read and did no other statements in my file.
Sorry for the lengthy post but I have been researching this all week and could not find any information on why this was happening, thank you all in advance.
I have a simple PHP script that enables users to upload images on a server. I am after some help in displaying these images as thumbnails in an HTMl page and then letting the user click on these thumbnails and then the original picture is displayed in a new page.
Can I use straight HTML for this? Or do I need some combination of javascript or PHP variant?
I know that there are many questions about this on stackoverflow, and I have tried them, but nothing is what I am after.
I would prefferably like the thumbnails be created on the 'fly' rather than me personally having to create each thumbnal when a user uploads an image.
So basically what language should I use to do this? And also can I have some source code if possible?
thanks
Creating thumbnails every time they are requested is a very bad idea - it takes a lot of processing power, which would be easily saved by keeping them around the first time you create them. I would suggest putting the thumbnail creation in the php script that processes the file upload, so that you save the image and its thumbnail to disk at the same time. You can also keep the thumbnail in memory, or wait until the first time it's requested to create it, but either way you cannot re-generate it every time it is requested.
It is possible to use html to change an image's size, by simply setting the width and/or height properties:
<img src='foo.jpg' alt='foo' width='500' height='300'/>
However, this is a bad idea if you aren't certain that the user will later want to view the full-sized image. The reason is that a thumbnail has a smaller filesize than the full image: if the client only wants to view the thumbnail, then you don't want to waste bandwidth (= your money and the client's time) sending them the full image.
As for your interface, you don't need javascript to accomplish that, just html. However, you will need a server-side script to create the thumbnails that your html page links to.
There are plenty of php thumbnail scripts out there.
Either you use a rewriter to still show the original path, but server a php thumbnail version. Or you have to have the url change to something like:
<img src="thumb.php?file=path/to/picture.jpg&size=128" />
Mighty Stuff
phpThumb
Are just such two. Best configured to utilize the cached folder. I use a modified version of the first script at work.
Here's a PHP script you can build appon only works with jpg images.
It will scan through a directory, normalize the image to a decent dimension and also make a thumb on the fly, then on next refresh it wont need to reprocess the image as its already present in the thumbs dir. Hope it helps...
Script placement
Root>
thisscript.php
/images/
someimage.jpg
someimage2.jpg
thisscript.php
<?php
// config section
$path = "./images/";
$thpath = $path."thumbs/";
// end configration
// Open the directory
$do = dir($path);
// now check if the thumb dir is available if not, create it!!
if (!is_dir($thpath)){
mkdir($thpath);
}
$output = '<div>';
while (($file = $do->read()) !== false){
if (is_dir($path.$file)){
continue;
}else{
$info = pathinfo($path.$file);
$fileext = $info['extension'];
if (strtolower($fileext) == 'jpg'){
if (!is_file($thpath.$file)){
//Normalize Super lrg Image to 750x550
thumb_it($path, $file, $path,750,550,99);
//Make Thumb 200x125
thumb_it($path, $file, $thpath,200,125,99);
$output .='<p><img src="'.$thpath.$file.'" title="" alt="" /></p>';
}else{
$output .='<p><img src="'.$thpath.$file.'" title="" alt="" /></p>';
}
}
}
}
$output .='</div>';
echo $output;
//Functions
function thumb_it($dirn, $file, $thumbdir,$rwidth,$rheight,$quality){
set_time_limit(0);
$filename = $dirn.$file;
$thfilename = $thumbdir.preg_replace('/[^a-zA-Z0-9.-]/s', '_', $file);
// get the filename and the thumbernail directory
if (is_file($filename)){
// create the thumbernail from the original picture
$im = #ImageCreateFromJPEG($filename);
if($im==false){return false;}
$width = ImageSx($im); // Original picture width is stored
$height = ImageSy($im); // Original picture height is stored
if (($width < $rwidth) && ($height < $rheight)){
$n_height = $height;
$n_width = $width;
}else{
// saveing the aspect ratio
$aspect_x = $width / $rwidth;
$aspect_y = $height / $rheight;
if ($aspect_x > $aspect_y){
$n_width = $rwidth;
$n_height = $height / $aspect_x;
}else{
$n_height = $rheight;
$n_width = $width / $aspect_y;
}
}
$newimage = imagecreatetruecolor($n_width, $n_height);
// resizing the picture
imageCopyResized($newimage, $im, 0, 0, 0, 0, $n_width, $n_height, $width, $height);
// writing to file the thumbnail
if(file_exists($thfilename)){chmod($thfilename, 0777);}
Imagejpeg($newimage, $thfilename, $quality);
imagedestroy($newimage);
imagedestroy($im);
}
}
?>
I'm having an issue using a watermarking script I have. Below is the script:
if (isset($_GET['imgid'])) {
include "../mysql_connect.php";
$imgid = $_GET['imgid'];
$query = "SELECT * FROM img_ref WHERE id='$imgid'";
$result = mysql_query($query) or die(mysql_error());
$row = mysql_fetch_array($result);
$imagesource = "../ajax_uploads/$row[submitter_id]-uploads/$row[filename]";
} else {
$imagesource = "../ajax_uploads/" . $_GET['path'];
}
$info = pathinfo($imagesource);
$filetype = $info['extension'];
if($filetype == "gif") $image = #imagecreatefromgif($imagesource);
if($filetype == "jpg") $image = #imagecreatefromjpeg($imagesource);
if($filetype == "png") $image = #imagecreatefrompng($imagesource);
if (!$image) die();
$watermark = #imagecreatefrompng('../images/watermark.png');
// This is the key. Without ImageAlphaBlending on, the PNG won't render correctly.
imagealphablending($image, true);
$imagewidth = imagesx($image);
$imageheight = imagesy($image);
$watermarkwidth = imagesx($watermark);
$watermarkheight = imagesy($watermark);
$startwidth = (($imagewidth - $watermarkwidth)/2);
$startheight = (($imageheight - $watermarkheight)/2);
imagecopy($image, $watermark, $startwidth, $startheight, 0, 0, $watermarkwidth, $watermarkheight);
imagejpeg($image);
imagedestroy($image);
imagedestroy($watermark);
Now, if I pass a 'path' variable through, everything works fine and the image is displayed correctly as I would imagine. However, when I attempt to pass through an imgid value, and retrieve the path from the database, the image is presented in raw data on the screen - not as an image.
I have tried specifying the headers
header("Content-type: image/jpeg");
However that hasn't helped. It doesn't seem to be an issue with the folder permissions, as if I specify the path name using the reference in the database, it works fine. It seems to be that including that first "if" section seems to break the output, and I'm at a loss why.
Could anyone possibly shed any light on this for me?
Thank you kindly,
Dan
UPDATE
Okay, somehow its started working with having "Header("Content-type: image/jpeg");" placed at the top of the PHP file, so if I go to the file directly and put in the GET id, I get the picture returned - which is good (no idea what changed though).
However I still have an issue in displaying this picture elsewhere it seems. I'm calling the picture using "fancybox", a jquery plugin. When it displays the image, it is still showing the raw data. If I use the path, it displays fine - just for some reason the raw data shows up when using the GET id option. Am still looking into it but thanks for suggestions so far.
It seems using the header
header("Content-type: image/jpeg");
Seemed to work to get it to display as an image - however it did not work with fancybox for some reason. I looked at the API and have sinced forced fancybox to realise it is an image:
$.fancybox({
'href':'processes/process_watermark.php?imgid=' + id,
'type':'image'
});
That makes it display correctly.
Thanks for everyones help - and all the comments reminding me about SQL attacks.
You don't checking fail of mysql_fetch_array maybe query dont result anything?
Maybe path you giving to pathinfo is not correct.
Your debugging script you should have at the top of script error_reporting(E_ALL)
Change $imagesource = "../ajax_uploads/$row[submitter_id]-uploads/$row[filename]"; to $imagesource = "../ajax_uploads/" . $row['submitter_id'] . "-uploads/" . $row['filename'];
I am working on improving one of my Facebook apps by allowing the user to upload an image and apply a styled border, or frame to it (i.e. clouds, stars, sky etc). The user chould also be able to save the image, with the border after it has been applied. This explains a little better what I need:
http://zbrowntechnology.info/ImgDisp/imgdisp.php
If you have any other questions or need more details, please let me know.. I'll edit this post.
Use imagecopy(). The example on that page is done using the transparency option with imagecopymerge() but I don't think you need that.
Using imagecopy() you'll specify the X/Y coordinates to use for positioning:
imagecopy( $borderimage, $topimage, 20, 20, 0, 0, $width, $height);
Where $width and $height will be the entire width and height of the top image. You'll want to replace 20 and 20 with the measurement for how much of the border image will be showing around the borders. You will probably have to resize the top image to the exact dimensions you want, or else it might overlap the border a little too far to the right or bottom. (see imagecopyresampled())
Edit:
Here's a rough way to do the whole process (assuming chosenborder.png is the border they chose, and uploadedimage.png is the image they uploaded. If it's a different image type you'll use the corresponding function).
$borderx = 20; // The width of our border
$border = imagecreatefrompng("chosenborder.png");
$topimage = imagecreatefrompng("uploadedimage.png");
$bordersize = getimagesize($border);
$topimagesize = getimagesize($topimage);
/* The new dimensions of topimage. $borderx*2 means we account for
the border on both left and right, top and bottom. */
$newx = $bordersize[0] - ($borderx*2);
$newy = $bordersize[1] - ($borderx*2);
imagecopyresampled( $topimage_scaled, $topimage, 0, 0, 0, 0,
$newx, $newy, $topimagesize[0], $topimagesize[1]);
/* Merge the images */
imagecopy( $border, $topimage_scaled, $borderx, $borderx,
0, 0, $width, $height);
/* Output the image */
imagepng($border, "newimage.png");
/* Free up the memory occupied by the image resources */
imagedestroy($border);
imagedestroy($topimage);
After the user uploads their image, find chosenborder.png and uploadedimage.png, run the above script, then display newimage.png to the user and you're good to go. Just make sure you call imagedestroy() on the temporary image resources or they'll eat up memory.
If you don't want to keep the generated image on your server, you can omit the second argument to imagepng() which will make it send the image information directly as an image to the browser, in which case you'll want to write the correct image HTTP headers.
Client-side solution by using css3:
checkout the css3 property border-image
(dosen't meet the requirement of saving the img with the border)
Server-side solution by merging 2 different images:
<?php
$imgFile = 'img.jpg';
$brdFile = 'brd.jpg';
$img = addBorder($imgFile,$brdFile);
outputImage($img);
function addBorder($imgFile,$brdFile)
{
$img=imagecreatefromjpeg($imgFile);
$brd=imagecreatefromjpeg($brdFile);
$imgSize = getimagesize($imgFile);
$brdSize = getimagesize($brdFile);
//NOTE: the border img MUST be bigger then the src img
$dst_x = ceil(($brdSize[0] - $imgSize[0])/2);
$dst_y = ceil(($brdSize[1] - $imgSize[1])/2);
imagecopymerge ( $brd, $img, $dst_x, $dst_y, 0, 0, $imgSize[0], $imgSize[1] ,100 );
return $brd;
}
function outputImage($img)
{
header('Content-type: image/png');
imagepng($img);
}
?>