Създавайте миниатюри от съхранени в mysql изображения

Имам таблица с име потребители и всеки ред (потребител) има изображение.

Изображението се съхранява като BLOB в mysql база данни с помощта на този код:

$filename = $_FILES['image']['tmp_name'];
$size = getimagesize($filename);
$handle = fopen( $filename , "rb" );
$content = fread( $handle , filesize( $filename ) );
fclose( $handle );
unlink($filename);
$image = base64_encode( $content );
//  .... send query to database ....

Това работи в началото, но тъй като все повече и повече изображения трябва да се показват на всяка страница, тя наистина се зарежда, така че сега искам да създам миниатюри, запазени във файловата система на сървъра, използвайки php GD.

Имам следния код, но нямам представа какво да направя, за да прочета изображението от базата данни, за да мога да създам неговата миниатюра.

$query = "SELECT * FROM users;";
$result = mysql_query( $query );
while( $row = mysql_fetch_array( $result ) ) {
    $uploaded_image = base64_decode( $row['image'] );
    $size = getimagesize($uploaded_image);  <--------------------
    $dimension_x = 73;
    $dimension_y = 73;
    $directory = 'views/images/generated/people/';
    do{
    $filename = random_32();
    $filename = $directory.$filename.'.jpg';    
    } while( file_exists($filename) );
$image = imagecreatefromjpeg( $uploaded_image );
$thumb = imagecreatetruecolor( $dimension_x , $dimension_y );
$size = getimagesize( $uploaded_image );
imagecopyresampled( $thumb , $image , 0 , 0 , 0 , 0 , $dimension_x , $dimension_y , $size['0'], $size['1']);
imagejpeg( $thumb , $filename , 100);
}

Опитвам се да намеря какво трябва да сложа там, където е стрелката, за да работи скриптът.

Всичко, което прави сега, е изход

Warning: getimagesize(ÿØÿà): failed to open stream: No such file or directory in /var/www/play/ns4/models/create_thumbs_people.php on line 12

За всеки запис в базата данни.

---- РЕДАКТИРАНЕ ----

Забравих да спомена, че random_32() е функция, която генерира случаен низ с дължина 32 знака, така че изображенията да бъдат именувани.


person ppp    schedule 29.01.2012    source източник


Отговори (2)


И ето една от многото причини, поради които съхраняването на файлове в базата данни е лоша идея...

getimagesize() работи с файлове, а не с низове. Тъй като имате необработеното изображение в низ, използвайте imagecreatefromstring(), след това imagesx() и функции imagesy(), за да получите размерите:

while( $row = mysql_fetch_array( $result ) ) {
    $uploaded_image = base64_decode( $row['image'] );
    $image = imagecreatefromstring( $uploaded_image );
    $uploaded_x = imagesx($image); // X dimension
    $uploaded_y = imagesy($image); // Y dimension
    etc....

Имайте предвид, че imagecreatefromstring всъщност има малко интелигентност и може да разбере какъв тип е изображението, за разлика от доста идиотичните функции createfromgif/jpg/png/etc..., които работят само с тези конкретни типове файлове.

person Marc B    schedule 29.01.2012
comment
Опитах кода ви, промених стойностите в imagecopyresampled и работи като чар! - person ppp; 29.01.2012

На прав път сте, проблемът е, че $uploaded_image е съдържанието на изображението, а не пътят към файла. getimagesize изисква име на файл като първи аргумент.

Концептуално, ето промяната, която трябва да се направи:

  • запишете съдържанието на $uploaded_image на временно място
  • извикайте getimagesize на това временно местоположение

Ето примерен код (нетестван):

$uploaded_image = base64_decode( $row['image'] );  //this is from your code above, should work fine
$uploaded_temp_file = tempnam(sys_get_temp_dir(), 'user_image');    //generate a temporary file name in your OS's temp folder
$uploaded_temp_res = fopen($uploaded_temp_file, 'wb');    //open the file for binary write
fwrite($uploaded_temp_res, $uploaded_image);   //commit binary data to the file
fclose($uploaded_temp_res);     //close the file handle
$size = getimagesize($uploaded_temp_file);      //finally, get the image size

Имайте предвид, че ще искате да добавите обработка на грешки и какво ли още не.

person Patrick Shafer    schedule 29.01.2012
comment
благодаря ви за отделеното време. Вече бях тръгнал по друг начин, когато видях отговора ви, така че направих това, което предложи @Marc B. - person ppp; 29.01.2012