обновление записей с размерами изображения в базе данных. Я хочу ждать меньше 10 часов

У меня есть большая таблица mysql необработанных изображений с более чем 1 200 000 строк (по 1 строке на изображение) в формате innoDB, но я буду работать с 600 000 строк. Что я хочу сделать быстро, так это извлечь локальное имя файла изображения из базы данных, определить его размер и размеры, а затем сохранить данные обратно в базу данных.

Выполнение ввода-вывода в базе данных без вычислений изображения выполняется быстро, потому что у меня настроены параметры MySQL оптимально. Фактически, я настроил один буфер, чтобы он был больше, чем весь размер самого большого размера файла базы данных mysql.

В настоящее время мой код для расчета размеров и размеров изображения таков:

$img='/path/to/current/image/to/find/dimensions/for.jpg';
$ifs=-1;
$iw=-1;
$ih=-1;
if ($ifs=@filesize($img)){
$im=NULL;
$im=@imagecreatefromjpeg($img);
if ($im){
$iw=imagesx($im);
$ih=imagesy($im);
imagedestroy($im);
}
$im=NULL;
}

Есть ли способ преобразовать этот код в формат, который занимает значительно меньше времени для выполнения?

Помните. Я имею дело с локальными изображениями, и приведенный выше код выполняется 600 000 раз, поэтому здесь важны оптимизации, и любой код, который экономит мне даже одну миллисекунду времени выполнения, будет оценен.

Все изображения в формате JPEG и размеры часто варьируются от 600x400px до 800x533px

Есть идеи?

0

Решение

В php.net есть комментарий пользователя в документации getimagesize () он не читает весь файл jpeg, чтобы узнать размеры, так как размеры сохраняются после части заголовка файла. Код специфичен для JPEG, не может использоваться для других типов файлов.

Этот код должен быть быстрее вашего, так как он умирает, не читает весь файл и не создает из него ресурс.

<?php
// Retrieve JPEG width and height without downloading/reading entire image.
function getjpegsize($img_loc) {
$handle = fopen($img_loc, "rb") or die("Invalid file stream.");
$new_block = NULL;
if(!feof($handle)) {
$new_block = fread($handle, 32);
$i = 0;
if($new_block[$i]=="\xFF" && $new_block[$i+1]=="\xD8" && $new_block[$i+2]=="\xFF" && $new_block[$i+3]=="\xE0") {
$i += 4;
if($new_block[$i+2]=="\x4A" && $new_block[$i+3]=="\x46" && $new_block[$i+4]=="\x49" && $new_block[$i+5]=="\x46" && $new_block[$i+6]=="\x00") {
// Read block size and skip ahead to begin cycling through blocks in search of SOF marker
$block_size = unpack("H*", $new_block[$i] . $new_block[$i+1]);
$block_size = hexdec($block_size[1]);
while(!feof($handle)) {
$i += $block_size;
$new_block .= fread($handle, $block_size);
if($new_block[$i]=="\xFF") {
// New block detected, check for SOF marker
$sof_marker = array("\xC0", "\xC1", "\xC2", "\xC3", "\xC5", "\xC6", "\xC7", "\xC8", "\xC9", "\xCA", "\xCB", "\xCD", "\xCE", "\xCF");
if(in_array($new_block[$i+1], $sof_marker)) {
// SOF marker detected. Width and height information is contained in bytes 4-7 after this byte.
$size_data = $new_block[$i+2] . $new_block[$i+3] . $new_block[$i+4] . $new_block[$i+5] . $new_block[$i+6] . $new_block[$i+7] . $new_block[$i+8];
$unpacked = unpack("H*", $size_data);
$unpacked = $unpacked[1];
$height = hexdec($unpacked[6] . $unpacked[7] . $unpacked[8] . $unpacked[9]);
$width = hexdec($unpacked[10] . $unpacked[11] . $unpacked[12] . $unpacked[13]);
return array($width, $height);
} else {
// Skip block marker and read block size
$i += 2;
$block_size = unpack("H*", $new_block[$i] . $new_block[$i+1]);
$block_size = hexdec($block_size[1]);
}
} else {
return FALSE;
}
}
}
}
}
return FALSE;
}
?>
1

Другие решения

Я использовал этот код размера JPEG раньше, он может быть основан на коде, опубликованном в другом ответе!

Подготовленные операторы сэкономят много накладных расходов при вставке в базу данных.

#!/usr/bin/env php
<?php
$db     = new PDO("mysql:host=localhost;dbname=images", "username", "password");
$images = $db->query("SELECT id, filename FROM images", PDO::FETCH_NUM);
$stmt   = $db->prepare("INSERT INTO images SET width = ?, height = ? WHERE id = ?");

foreach ($images as $image) {
list($w, $h) = jpgsize($image[1]);
$stmt->execute(array($w, $h, $image[0]));
}

$db->close();

function jpgsize($img) {
$h = fopen($img, "rb") or return false;
$block = null;
if(feof($h)) {
fclose($h);
return false;
}
$block = fread($h, 32);
if (substr($block, 0, 4) === "\xFF\xD8\xFF\xE0" && substr($block, 6, 5) === "\x4A\x46\x49\x46\x00") {
$block_size = unpack("H*", substr($block, 4, 2));
$block_size = hexdec($block_size[1]);
$i = 4;
while(!feof($h)) {
$i += $block_size;
$block .= fread($h, $block_size);
if(substr($block, $i, 1) === "\xFF") {
$sof_marker = array("\xC0", "\xC1", "\xC2", "\xC3", "\xC5", "\xC6", "\xC7", "\xC8", "\xC9", "\xCA", "\xCB", "\xCD", "\xCE", "\xCF");
if(in_array(substr($block, $i+1, 1), $sof_marker)) {
$size_data = substr($block, $i + 2, 7);
$unpacked = unpack("H*", $size_data);
$unpacked = $unpacked[1];
$height = hexdec(substr($unpacked, 6, 4));
$width = hexdec(substr($unpacked, 10, 4));
fclose($h);
return array($width, $height);
} else {
$i += 2;
$block_size = unpack("H*", substr($block, $i, 2));
$block_size = hexdec($block_size[1]);
}
} else {
fclose($h);
return false;
}
}
}
fclose($h);
return false;
}
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector