Я поддерживаю сайт с базой данных примерно из 30000 изображений, связанных с списком. Изображения имеют много разных размеров и форматов изображения, поэтому, чтобы представить их на сайте единообразно, я написал функцию, которая позволяет мне представлять изображение в ответ с определенным соотношением сторон.
function image($src,$aspect) {
$html = '<img class="img-responsive" src="furniture/blank-'.$aspect.'.png" style="background:url(\''.$src.'\');background-position:center center;background-size:cover;" >';
return $html;
}
В моей папке «furniture» у меня есть набор прозрачных файлов PNG с желаемым соотношением сторон, чтобы задать размер контейнера, для которого фактическое изображение становится фоном. Так, например, есть файл 4×3.png, который представляет собой пустой пустой рисунок шириной 4 на 3 пикселя, который я могу вызвать с помощью изображения (‘path / to / image.jpg’, ‘4×3’) — он работает довольно хорошо.
Однако проблема возникает, когда на изображении есть чье-то лицо, так как стандартное позиционирование по центру может иногда отрезать головы.
Я уже проделал этап обнаружения лица, и у каждой записи в базе данных есть флаг о том, было ли найдено лицо на изображении, и, если да, значения X, Y и Width. Затем проблема состоит в том, чтобы выяснить положение фона, потому что я имею дело с адаптивным макетом, поэтому не обязательно знать, какой размер изображения отображается.
Я предполагаю, что логика, которой я должен следовать, такова;
Если изображение имеет лицо в нем
ТО затем установите положение фона с вертикальным смещением, рассчитанным на основе координаты Y грани.
ELSE
установить положение фона в центр
Как определить значение вертикального смещения, учитывая, что размер изображения неизвестен?
Хорошо, так что я понял это, но пост здесь на случай, если кто-то еще борется с этим.
Основная логика состоит в том, чтобы определить высоту окна аспекта на основе ширины фактического изображения (не нужно беспокоиться об отзывчивом характере на данном этапе). Затем вы находите идеальную центральную точку изображения, чтобы поместить ее в рамку, и решаете, находится ли эта точка выше или ниже пределов того, как ваше изображение может скользить в пределах вашего аспектного окна.
Я помещаю это в функцию, которую я вызываю, а затем перетаскиваю результат прямо в CSS-положение фона.
Ниже приведены переменные:
$ faceW = ширина (и высота) площади лица
function calcImagePosition($img,$aspect1,$aspect2,$faceD,$faceY,$faceW) {
if($faceD==1) { // Only do this if there's a face in the image
list($width, $height) = getimagesize($_SERVER['DOCUMENT_ROOT']."/".$img); // Get the image dimensions
$aspectHeight = ($width/$aspect1)*$aspect2; // Get the height of the aspect window based on the actual width of the image
$idealCentre = $faceY + ($faceW/2); // The best part of the image to appear in the aspect window is halfway down the face bounds
if($idealCentre<($aspectHeight/2)) { // if the ideal centre is higher than half the height of the aspect window, just set it to top
$position = "center top";
} elseif(($height-$idealCentre)<($aspectHeight/2)) { // Also, if there's less than half the height of the aspect window at the bottom, set it to bottom
$position = "center bottom";
} else { // This will slide the position to best match the face
$pixel = $idealCentre-($aspectHeight/2); // Get the absolute pixel value
$percent = intval(($pixel/$height)*100); // Convert this to a percentage so it doesn't matter about responsive sizing
$position = "center ".$percent."%";
}
} else {
$position = "center center"; // default for no face detection
}
return $position;
}
Я использую это в сочетании с php-портом Karthik Tharavaad детектора лиц, который выполняет разумную работу по созданию данных, необходимых для $ faceY и $ faceW.
Других решений пока нет …