PHP kod för att förminska en bild innan den skrivs till databasen

Tråden skapades och har fått 3 svar. Det senaste inlägget skrevs .
1

Koden funkar fint om jag sätter $skip = 1, men inte när jag sätter $skip = 0, dvs när $skip = 0, skall databasen förminska bilden innan den sparas i databasen. När $skip = 1 förminskas bilden ej. Vad gör jag för fel?

<html>
<head>
<title>Test plattform</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="robots" content="noindex,nofollow" />
</head>
<body>
<?php
$database = "PictureStorage";
$server = "192.168.0.8";
$db_user = "xxx";
$db_password = "xxxx";

function resizeImage ($picture,$max_height) {
	// get originalsize of image
	$im = imagecreatefromstring($picture);
	$width = imagesx($im);
	$height = imagesy($im);
	
	// Set thumbnail-height to x pixels
	$imgh = $max_height;
	
	// calculate thumbnail-height from given width to maintain aspect ratio
	$imgw = round($width / $height * $imgh);
	
	// create new image using thumbnail-size
	$resizedImage=imagecreatetruecolor($imgw,$imgh);
	// copy original image to thumbnail
	imagecopyresampled($resizedImage,$im,0,0,0,0,$imgw,$imgh,imagesx($im),imagesy($im)); //makes thumb
	$picture_array = array($resizedImage,$imgw, $imgh);
	return $picture_array;
}

if ($_POST['submit']) {
	if (isset($_FILES['file']) && $_FILES['file']['size'] > 0) {
		$picture_ID = 1;
		$skip = 1;
		echo "Reading file…<br>\n";
		
		$fileName = $_FILES['file']['name'];
		$fileSize = $_FILES['file']['size'];
		$fileType = $_FILES['file']['type'];
	
		// Temporary file name stored on the server
		$tmpName = $_FILES['file']['tmp_name'];
		
		// Read the file
		$fp =fopen($tmpName, 'r');
		$data1 = fread($fp, filesize($tmpName));
		$data = addslashes($data1);
		$picture = $data;
		fclose ($fp);
		echo "Temporary file name: $tmpName<br>\n";
		
//		imagejpeg($data1, null, 100);
		// Resize picture
		
		echo "Inserting picture in normal size into database<br>\n";
		if ($skip == 0) {
			$picture_array = resizeImage ($data1, 480);
			$picture = $picture_array[0];
			$imgw = $picture_array[1];
			$imgh = $picture_array[2];
		} else {
			$im = imagecreatefromstring($data1);
			$imgw = imagesx($im);
			$imgh = imagesy($im);
		}
//		imagejpeg($picture, null, 100);
		$link = mysqli_connect($server, $db_user, $db_password);
		if (mysqli_connect_errno()) {
			printf("<b>Connection failed:</b> %s<br>", mysqli_connect_error());
		} else {
			mysqli_select_db($link, $database);
			
			$result = mysqli_query($link,"SET global max_allowed_packet=1073741824") or die( "<b>An error has occurred:</b> " .mysqli_error($link). ". <b>Error number:</b> " .mysqli_errno($link));
			
			if ($picture_ID) {
				$query = ("UPDATE PictureStorage SET Data_normal = '$picture', Name_normal = '$fileName', Type_normal = '$fileType', Pixel_width_normal = '$imgw', Pixel_height_normal = '$imgh' WHERE Picture_ID = '$picture_ID' ");
			} else {
				$query = ("INSERT PictureStorage (Data_normal, Name_normal, Type_normal, Pixel_width_normal, Pixel_height_normal) VALUES ('$picture','$fileName','$fileType','$imgw','$imgh')");
			}
			$result = mysqli_query($link,$query) or die( "<b>An error has occurred:</b> " .mysqli_error($link). ". <b>Error number:</b> " .mysqli_errno($link));
			
		}
		mysqli_close($link);

		
		echo "Inserting picture in mini size into database<br>\n";
		// Thumbnail size
		if ($skip == 0) {
			$picture_array = resizeImage ($data1, 120);
			$picture_mini = $picture_array[0];
			$imgw_mini = $picture_array[1];
			$imgh_mini = $picture_array[2];
		} else {
			$im_mini = imagecreatefromstring($data1);
			$imgw_mini = imagesx($im_mini);
			$imgh_mini = imagesy($im_mini);
		}
		$link = mysqli_connect($server, $db_user, $db_password);
		if (mysqli_connect_errno()) {
			printf("<b>Connection failed:</b> %s<br>", mysqli_connect_error());
		} else {
			mysqli_select_db($link, $database);
			
			$result = mysqli_query($link,"SET global max_allowed_packet=1073741824") or die( "<b>An error has occurred:</b> " .mysqli_error($link). ". <b>Error number:</b> " .mysqli_errno($link));
			
			if ($picture_ID) {
				$query = ("UPDATE PictureStorage SET Data_mini = '$picture_mini', Name_mini = '$fileName', Type_mini = '$fileType', Pixel_width_mini = '$imgw_mini', Pixel_height_mini = '$imgh_mini' WHERE Picture_ID = '$picture_ID' ");
			} else {
				$query = ("INSERT PictureStorage (Data_mini, Name_mini, Type_mini, Pixel_width_mini, Pixel_height_mini) VALUES ('$picture_mini','$fileName','$fileType','$imgw_mini','$imgh_mini')");
			}
			$result = mysqli_query($link,$query) or die( "<b>An error has occurred:</b> " .mysqli_error($link). ". <b>Error number:</b> " .mysqli_errno($link));
		}
		mysqli_close($link);

	} else {
		echo "Could not read file…<br>\n";
	}
} else {
	$link = mysqli_connect($server, $db_user, $db_password);
	if (mysqli_connect_errno()) {
		printf("<b>Connection failed:</b> %s<br>", mysqli_connect_error());
	} else {
		mysqli_select_db($link, $database);
		$query = ("SELECT * FROM PictureStorage");
		$result = mysqli_query($link,$query) or die( "<b>An error has occured:</b> " .mysqli_error($link). ". <b>Error number:</b> " .mysqli_errno($link));
		
		$numberofitems = 0;
		echo "<table border='1' cellspacing='0' cellpadding='2'>\n";
		echo "<tr><th></th><th colspan='5'>Normal size</th><th></th><th colspan='5'>Mini size</th></tr>\n";
		echo "<tr><th>ID</th><th>Picture</th><th>File name</th><th>Type</th><th>Width</th><th>Height</th><th>||</th><th>Picture</th><th>File name</th><th>Type</th><th>Width</th><th>Height</th></tr>\n";
		while ($row = mysqli_fetch_array($result, MYSQLI_BOTH)) {
			$ID = $row['Picture_ID'];
			$name = $row['Name_normal'];
			$type = $row['Type_normal'];
			$width = $row['Pixel_width_normal'];
			$height = $row['Pixel_height_normal'];
			$picture = $row['Data_normal'];
			$name_mini = $row['Name_mini'];
			$type_mini = $row['Type_mini'];
			$width_mini = $row['Pixel_width_mini'];
			$height_mini = $row['Pixel_height_mini'];
			$picture_mini = $row['Data_mini'];
			
			echo "<tr>";
			echo "<td>" . $ID . "</td>";
			echo "<td>";
			echo "<img src='data:$type;base64, ". base64_encode($picture) . "' alt='En bild'>";
			//echo "<img src='data:image/jpg; ". $picture . "' alt='En bild'>";
			//imagejpeg($picture, NULL, 100);
			echo "</td>";
			echo "<td>" . $name . "</td>";
			echo "<td>" . $type . "</td>";
			echo "<td>" . $width . "</td>";
			echo "<td>" . $height . "</td>";
			echo "<td>||</td>";
			echo "<td>";
			echo "<img src='data:$type;base64, ". base64_encode($picture_mini) . "' alt='En mini bild'>";
			echo "</td>";
			echo "<td>" . $name_mini . "</td>";
			echo "<td>" . $type_mini . "</td>";
			echo "<td>" . $width_mini . "</td>";
			echo "<td>" . $height_mini . "</td>";
			echo "</tr>\n";
			$numberofitems++;
		}
		echo "<tr><th colspan=12>" . $numberofitems;
		if ($numberofitems > 1) {
			echo " items";
		} else {
			echo " item";
		}
		echo "</th></tr>\n";
		echo "</table>\n";
	}
	
	$html .= "<hr>";
	$html .= "<form action='Test4.php' method='post' enctype='multipart/form-data'>";
	$html .= "<label for = 'file'>Filename:</label>";
	$html .= "<input type='file' name='file' id='file'><br>";
	$html .= "<input type='submit' name='submit' value='Submit'>";
	$html .= "</form>";
	echo $html;
}
?>
</body>
</html>
Senast redigerat 2013-08-02 15:55
Ursprungligen av The Real Viking:

Koden funkar fint om jag sätter $skip = 1, men inte när jag sätter $skip = 0, dvs när $skip = 0, skall databasen förminska bilden innan den sparas i databasen. När $skip = 1 förminskas bilden ej. Vad gör jag för fel?

Den första orsaken till att inget sparas tycks vara att koden blandar datatyper. När du först läser in $picture på rad 51 så är det en bytearray/sträng, men resizeImage() returnerar en resurs. Innan du kan skicka den till databasen så måste du spara den i ett av de tillgängliga bildformaten igen:

<?php
function resizeImage ($inString, $maxHeight)
{
    $originalImage  = imagecreatefromstring($inString);
    $originalWidth  = imagesx($originalImage);
    $originalHeight = imagesy($originalImage);
    
    $newHeight      = $maxHeight;
    $newWidth       = round($originalWidth  / $originalHeight * $maxHeight);
    
    $resizedImage   = imagecreatetruecolor($newWidth, $newHeight);
    
    imagecopyresampled($resizedImage, $originalImage, 0, 0, 0, 0, $newWidth, $newHeight, $originalWidth, $originalHeight);
    
    //
    // !!! Bilden som en sträng istället för gd-resurs
    //
    ob_start();
    imagejpeg($resizedImage);
    $outString = ob_get_clean();
    
    return array($outString, $newWidth, $newHeight);
}
?>

Ett annat problem som kan hindra dina bilder från att sparas är att datan inte escapas i dina queries. Detta kan leda till att de färdiga kommandona blir ogiltiga eller utför något annat än vad du hade tänkt dig. Eftersom att ditt API (ext/mysqli) har stöd för prepared statements så skulle jag rekommendera att du tar reda på hur man använder sig av det, det gör det betydligt svårare att begå den här typen av misstag. Det kan även hända att du finner PDO lättare att arbeta med.

Snabbfix för att escapa och förbättra läsbarheten i vanliga queries:

$query = sprintf(
    'UPDATE
        PictureStorage
    SET
        Data_normal = "%s",
        Name_normal = "%s"
        ...',
    mysqli_real_escape_string($link, $picture),
    mysqli_real_escape_string($link, $name)
);

mysqli_query($query);

Exempel med PDO och prepared statements:

$sth = $dbh->prepare(
    'UPDATE
        PictureStorage
    SET
        Data_normal = :data,
        Name_normal = :name
        ...');

$sth->bindValue(":data", $picture, PDO::PARAM_STR);
$sth->bindValue(":name", $name, PDO::PARAM_STR);
$sth->execute();

Sedan finns det ett mindre problem med att spara en tumnagel om $picture_ID inte evaluerar till ett sannt värde (förtyliga gärna avsikten med det genom t.ex. if($picture_ID > 0) istället), och det är att $picture_mini bara definieras om $skip är 0 (rad 93). Om den här raden körs så borde du få ett felmeddelande som varnar för att du använder en odefinierad variabel. Kontrollera gärna att du har all felrapportering igång, det underlättar enormt om man hittar sådana missar direkt.

Har inte testat några av ändringarna eller exemplen. Se upp för typos och bekräfta med manualen...

Edit: Obligatoriskt skämt:

Senast redigerat 2013-08-02 20:21

Riktigt kul skämt, Luftvargen!

1000-tack för dina tips & råd!
Jag lyckades lösa problemet och nu fungerar det precis som tänkt. Det var både sträng/resurs problematiken och escape delen som strulade. När jag fixade båda fungerade det perfekt! Nu har jag lärt mig en hel del!

Senast redigerat 2013-08-03 07:48
Ursprungligen av The Real Viking:

Riktigt kul skämt, Luftvargen!

1000-tack för dina tips & råd!
Jag lyckades lösa problemet och nu fungerar det precis som tänkt. Det var både sträng/resurs problematiken och escape delen som strilade. När jag fixade båda fungerade det perfekt! Nu har jag lärt mig en hel del!

Kul att det hjälpte!

1
Bevaka tråden