/** * @param Color $color * @param int $accuracy * @return Part|null */ public function findOneWithColorLike($color, $accuracy) { // Пробуем найти полное соответствие цвета $partQb = $this->createQueryBuilder("part"); $partQb->join("part.avgColor", "color"); $partQb->andWhere($partQb->expr()->eq("color.red", $color->getRed())); $partQb->andWhere($partQb->expr()->eq("color.green", $color->getGreen())); $partQb->andWhere($partQb->expr()->eq("color.blue", $color->getBlue())); $partQb->andWhere($partQb->expr()->eq("part.active", true)); $parts = $partQb->getQuery()->execute(); /*$criteria = new Criteria(); $expressionRed = $criteria->expr()->andX( $criteria->expr()->gt("color.red", $color->getRed() - $accuracy), $criteria->expr()->lt("color.red", $color->getRed() + $accuracy) ); $expressionGreen = $criteria->expr()->andX( $criteria->expr()->gt("color.green", $color->getGreen() - $accuracy), $criteria->expr()->lt("color.green", $color->getGreen() + $accuracy) ); $expressionBlue = $criteria->expr()->andX( $criteria->expr()->gt("color.blue", $color->getBlue() - $accuracy), $criteria->expr()->lt("color.blue", $color->getBlue() + $accuracy) );*/ // Если не получилось то ищем похожие цвета с некоторой погрешностью if (count($parts) == 0) { $partQb = $this->createQueryBuilder("part"); $partQb->join("part.avgColor", "color"); // $partQb->andWhere($expressionRed); // $partQb->andWhere($expressionGreen); // $partQb->andWhere($expressionBlue); // $partQb->andWhere("color.red > ". ($color->getRed() - $accuracy)); // $partQb->andWhere("color.red < ". ($color->getRed() + $accuracy)); // $partQb->andWhere("color.green > ". ($color->getGreen() - $accuracy)); // $partQb->andWhere("color.green < ". ($color->getGreen() + $accuracy)); // $partQb->andWhere("color.blue > ". ($color->getBlue() - $accuracy)); // $partQb->andWhere("color.blue < ". ($color->getBlue() + $accuracy)); $partQb->andWhere($partQb->expr()->gt("color.red", $color->getRed() - $accuracy / 2)); $partQb->andWhere($partQb->expr()->lt("color.red", $color->getRed() + $accuracy / 2)); $partQb->andWhere($partQb->expr()->gt("color.green", $color->getGreen() - $accuracy / 2)); $partQb->andWhere($partQb->expr()->lt("color.green", $color->getGreen() + $accuracy / 2)); $partQb->andWhere($partQb->expr()->gt("color.blue", $color->getBlue() - $accuracy / 2)); $partQb->andWhere($partQb->expr()->lt("color.blue", $color->getBlue() + $accuracy / 2)); $partQb->andWhere($partQb->expr()->eq("part.active", true)); $parts = $partQb->getQuery()->execute(); } if (count($parts) > 0) { $index = rand(0, count($parts) - 1); return $parts[$index]; } return null; }
/** * Check segmentation need of image part * Проверяет необходимость деления части изображения * @param ImagickExt $imagick * @return bool */ private function needDividePart($imagick) { $width = $imagick->getWidth(); $height = $imagick->getHeight(); $topLeftPart = $imagick->getImageFromRect(0, 0, $width / 2, $height / 2); $bottomRightPart = $imagick->getImageFromRect($width / 2, $height / 2, $width, $height); $topRightPart = $imagick->getImageFromRect($width / 2, 0, $width, $height / 2); $bottomLeftPart = $imagick->getImageFromRect(0, $height / 2, $width / 2, $height); $sub1 = Color::compare($topLeftPart->getAvgColor(), $bottomRightPart->getAvgColor()); $sub2 = Color::compare($topRightPart->getAvgColor(), $bottomLeftPart->getAvgColor()); return ($sub1 + $sub2) / 2 > 8; }
/** * @param Color $color1 * @param Color $color2 * @return int */ public static function compare($color1, $color2) { $weight = 0; $weight += abs($color1->getRed() - $color2->getRed()); $weight += abs($color1->getGreen() - $color2->getGreen()); $weight += abs($color1->getBlue() - $color2->getBlue()); return $weight / 3; // TODO: divide on 3 }