Создание эскизов из сохраненных изображений 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