$picture = $_SERVER["DOCUMENT_ROOT"]."/upload/iblock/c89/c89bdc958fdbe9010394307fc83386e2.jpg"; $highloadBlock = 'eshop_color_reference'; CModule::IncludeModule('highloadblock'); CModule::IncludeModule('iblock'); $hlblock = Bitrix\Highloadblock\HighloadBlockTable::getList(array( "filter" => array( "=TABLE_NAME" => $highloadBlock, )))->fetch(); $entity = Bitrix\Highloadblock\HighloadBlockTable::compileEntity($hlblock); $entity_data_class = $entity->getDataClass(); $rsData = $entity_data_class::getList(array( "select" => array("ID", "UF_NAME", "UF_FILE", "UF_COLOR_R", "UF_COLOR_G", "UF_COLOR_B"), )); $colorReference = array(); while($arData = $rsData->fetch()) { if ( $arData["UF_FILE"] && ( !isset($arData["UF_COLOR_R"]) || !isset($arData["UF_COLOR_G"]) || !isset($arData["UF_COLOR_B"]) ) ) { $arFile = CFile::MakeFileArray($arData["UF_FILE"]); if ($arFile && CFile::ResizeImage($arFile, array("width"=>40,"height"=>40))) { $color = getPictureColor($arFile["tmp_name"], 10); $arData["UF_COLOR_R"] = $color["R"]; $arData["UF_COLOR_G"] = $color["G"]; $arData["UF_COLOR_B"] = $color["B"]; $entity_data_class::update($arData["ID"], array( "UF_COLOR_R" => $color["R"], "UF_COLOR_G" => $color["G"], "UF_COLOR_B" => $color["B"], )); } } $colorReference[] = $arData; } $arFile = CFile::MakeFileArray($picture); if ($arFile && CFile::ResizeImage($arFile, array("width"=>40,"height"=>40))) { $color = getPictureColor($arFile["tmp_name"], 10); foreach ($colorReference as &$arData) { $dR = $arData["UF_COLOR_R"] - $color["R"]; $dG = $arData["UF_COLOR_G"] - $color["G"]; $dB = $arData["UF_COLOR_B"] - $color["B"]; $distance = $dR*$dR + $dG*$dG + $dB*$dB; $arData["DISTANCE"] = $distance; } unset($arData); } \Bitrix\Main\Type\Collection::sortByColumn($colorReference, array("DISTANCE" => SORT_ASC)); var_dump(current($colorReference)); function getPictureColor($path, $border = 0) { $result = array( "R" => 0, "G" => 0, "B" => 0, ); $image = CFile::CreateImage($path); $width = imagesx($image); $height = imagesy($image); $c = 0; for ($x = $border; $x < $width-$border; $x++) { for ($y = $border; $y < $height-$border; $y++) { $c++; $rgb = imagecolorat($image, $x, $y); $result["R"] += (($rgb >> 16) & 0xFF); $result["G"] += (($rgb >> 8) & 0xFF); $result["B"] += ($rgb & 0xFF); } } if ($c) { foreach ($result as $i => $s) { $result[$i] = $s/$c; } } return $result; }
$picture = $_SERVER["DOCUMENT_ROOT"]."/upload/iblock/0d9/0d922f208991da15997032f1bb80b0f8.jpg"; $highloadBlock = 'eshop_color_reference'; CModule::IncludeModule('highloadblock'); CModule::IncludeModule('iblock'); $hlblock = Bitrix\Highloadblock\HighloadBlockTable::getList(array( "filter" => array( "=TABLE_NAME" => $highloadBlock, )))->fetch(); $entity = Bitrix\Highloadblock\HighloadBlockTable::compileEntity($hlblock); $entity_data_class = $entity->getDataClass(); $rsData = $entity_data_class::getList(array( "select" => array("ID", "UF_NAME", "UF_FILE", "UF_COLOR_R", "UF_COLOR_G", "UF_COLOR_B"), )); $colorReference = array(); while($arData = $rsData->fetch()) { if ( $arData["UF_FILE"] && ( !isset($arData["UF_COLOR_R"]) || !isset($arData["UF_COLOR_G"]) || !isset($arData["UF_COLOR_B"]) ) ) { $arFile = CFile::MakeFileArray($arData["UF_FILE"]); if ($arFile && CFile::ResizeImage($arFile, array("width"=>40,"height"=>40))) { $color = getPictureColor($arFile["tmp_name"], 10); $arData["UF_COLOR_R"] = $color["R"]; $arData["UF_COLOR_G"] = $color["G"]; $arData["UF_COLOR_B"] = $color["B"]; $entity_data_class::update($arData["ID"], array( "UF_COLOR_R" => $color["R"], "UF_COLOR_G" => $color["G"], "UF_COLOR_B" => $color["B"], )); } } $colorReference[] = $arData; } $arFile = CFile::MakeFileArray($picture); if ($arFile && CFile::ResizeImage($arFile, array("width"=>40,"height"=>40), BX_RESIZE_IMAGE_EXACT)) { copy($arFile["tmp_name"], $_SERVER["DOCUMENT_ROOT"]."/test.jpg"); echo '<img src="/test.jpg?'.rand(0,1000000).'"><br>'; $color = getPictureColor($arFile["tmp_name"], 10); var_dump($color);echo "<br>"; foreach ($colorReference as &$arData) { $c1 = rgb2xyz(array("R"=>$arData["UF_COLOR_R"],"G"=>$arData["UF_COLOR_G"],"B"=>$arData["UF_COLOR_B"])); $c1 = xyz2lab($c1); $c2 = rgb2xyz($color); $c2 = xyz2lab($c2); $dL = $c1["L"] - $c2["L"]; $dA = $c1["a"] - $c2["a"]; $dB = $c1["b"] - $c2["b"]; $distance = $dL*$dL + $dA*$dA + $dB*$dB; $arData["DISTANCE"] = $distance; echo $distance,"<br>"; } unset($arData); } \Bitrix\Main\Type\Collection::sortByColumn($colorReference, array("DISTANCE" => SORT_ASC)); var_dump(current($colorReference)); function getPictureColor($path, $border = 0) { $result = array( "R" => 0, "G" => 0, "B" => 0, ); $image = CFile::CreateImage($path); $width = imagesx($image); $height = imagesy($image); $c = 0; for ($x = $border; $x < $width-$border; $x++) { for ($y = $border; $y < $height-$border; $y++) { $c++; $rgb = imagecolorat($image, $x, $y); $result["R"] += (($rgb >> 16) & 0xFF); $result["G"] += (($rgb >> 8) & 0xFF); $result["B"] += ($rgb & 0xFF); } } if ($c) { foreach ($result as $i => $s) { $result[$i] = $s/$c; } } return $result; } function rgb2xyz($color) { $var_R = ( $color["R"] / 255 ); //R from 0 to 255 $var_G = ( $color["G"] / 255 ); //G from 0 to 255 $var_B = ( $color["B"] / 255 ); //B from 0 to 255 if ($var_R > 0.04045) $var_R = pow(($var_R + 0.055) / 1.055, 2.4); else $var_R = $var_R / 12.92; if ($var_G > 0.04045) $var_G = pow(($var_G + 0.055) / 1.055, 2.4); else $var_G = $var_G / 12.92; if ($var_B > 0.04045) $var_B = pow(($var_B + 0.055) / 1.055, 2.4); else $var_B = $var_B / 12.92; $var_R = $var_R * 100; $var_G = $var_G * 100; $var_B = $var_B * 100; //Observer. = 2°, Illuminant = D65 $result = array( "X" => $var_R * 0.4124 + $var_G * 0.3576 + $var_B * 0.1805, "Y" => $var_R * 0.2126 + $var_G * 0.7152 + $var_B * 0.0722, "Z" => $var_R * 0.0193 + $var_G * 0.1192 + $var_B * 0.9505, ); return $result; } function xyz2lab($color) { //Observer= 2°, Illuminant= D65 $var_X = $color["X"] / 95.047; $var_Y = $color["Y"] / 100.000; $var_Z = $color["Z"] / 108.883; if ($var_X > 0.008856) $var_X = pow($var_X, 1/3); else $var_X = (7.787 * $var_X) + (16 / 116); if ($var_Y > 0.008856) $var_Y = pow($var_Y, 1/3); else $var_Y = (7.787 * $var_Y) + (16 / 116); if ($var_Z > 0.008856) $var_Z = pow($var_Z, 1/3); else $var_Z = (7.787 * $var_Z) + (16 / 116); $result = array( "L" => ( 116 * $var_Y ) - 16, "a" => 500 * ($var_X - $var_Y), "b" => 200 * ($var_Y - $var_Z), ); return $result; }
и ОНО сбоит на некоторых картинках.
потестируй. расскажи о впечатлениях, плиз.
надо добавить поля "Число" в хайлоадблок UF_COLOR_R, UF_COLOR_G и UF_COLOR_B
алгоритм их заполнит при первом запуске.
Скоро будет лучший вариант