Jimage-L2 / index.php
JibayAi's picture
Upload 5 files
8e21c5e verified
<?php
header('Content-Type: text/html; charset=utf-8');
mb_internal_encoding('UTF-8');
function convertToUnicode($text) {
$persianChars = [
'آ' => '\u0622',
'ا' => '\u0627',
'ب' => '\u0628',
'پ' => '\u067e',
'ت' => '\u062a',
'ث' => '\u062b',
'ج' => '\u062c',
'چ' => '\u0686',
'ح' => '\u062d',
'خ' => '\u062e',
'د' => '\u062f',
'ذ' => '\u0630',
'ر' => '\u0631',
'ز' => '\u0632',
'ژ' => '\u0698',
'س' => '\u0633',
'ش' => '\u0634',
'ص' => '\u0635',
'ض' => '\u0636',
'ط' => '\u0637',
'ظ' => '\u0638',
'ع' => '\u0639',
'غ' => '\u063a',
'ف' => '\u0641',
'ق' => '\u0642',
'ک' => '\u06a9',
'گ' => '\u06af',
'ل' => '\u0644',
'م' => '\u0645',
'ن' => '\u0646',
'و' => '\u0648',
'ه' => '\u0647',
'ی' => '\u06cc',
' ' => '\u0020',
'۰' => '\u06f0',
'۱' => '\u06f1',
'۲' => '\u06f2',
'۳' => '\u06f3',
'۴' => '\u06f4',
'۵' => '\u06f5',
'۶' => '\u06f6',
'۷' => '\u06f7',
'۸' => '\u06f8',
'۹' => '\u06f9'
];
$unicodeText = '';
$chars = mb_str_split($text);
foreach ($chars as $char) {
if (isset($persianChars[$char])) {
$unicodeText .= $persianChars[$char];
} else {
$unicodeText .= $char;
}
}
return $unicodeText;
}
function generateTextImage() {
$text = $_GET['text'] ?? '';
$image_url = $_GET['image_url'] ?? '';
if (empty($text)) {
createErrorImage('text is empty');
return;
}
$tokensFile = __DIR__ . '/tokens.json';
$fontsFile = __DIR__ . '/fonts.json';
if (!file_exists($tokensFile)) {
createErrorImage('tokens not found');
return;
}
if (!file_exists($fontsFile)) {
createErrorImage('fonts not found');
return;
}
$tokensContent = file_get_contents($tokensFile);
$fontsContent = file_get_contents($fontsFile);
$tokens = json_decode($tokensContent, true);
$fonts = json_decode($fontsContent, true);
if ($tokens === null) {
createErrorImage('error in read tokens');
return;
}
if ($fonts === null) {
createErrorImage('error in read font');
return;
}
foreach (mb_str_split($text) as $char) {
$found = false;
foreach ($tokens as $token) {
if ($token['word'] === $char) {
$found = true;
break;
}
}
if (!$found) {
createErrorImage('Illegal characters in text');
return;
}
}
$lang = 'en';
foreach (mb_str_split($text) as $char) {
foreach ($tokens as $token) {
if ($token['word'] === $char && $token['language'] === 'persian/farsi/iran') {
$lang = 'fa';
break 2;
} elseif ($token['word'] === $char && $token['language'] === 'English') {
$lang = 'en';
break 2;
}
}
}
$langFonts = array_filter($fonts, function($font) use ($lang) {
return $font['lang'] === $lang;
});
$langFonts = array_values($langFonts);
if (empty($langFonts)) {
createErrorImage('font not found for this language');
return;
}
$selectedFont = $langFonts[array_rand($langFonts)];
$fontPath = __DIR__ . '/' . ($lang === 'fa' ? 'PersianFonts/' : 'EnglishFonts/') . $selectedFont['font-name'];
if (!file_exists($fontPath)) {
createErrorImage('font selected . not found');
return;
}
$ratios = [
[1, 1],
[1, 1],
[1, 1]
];
$ratio = $ratios[array_rand($ratios)];
$baseSize = 2000;
$width = $ratio[0] * ($baseSize / 2);
$height = $ratio[1] * ($baseSize / 2);
$image = imagecreatetruecolor($width, $height);
imagesavealpha($image, true);
$transparent = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($image, 0, 0, $transparent);
$externalImage = null;
if (!empty($image_url)) {
$externalImage = loadExternalImage($image_url);
}
if ($externalImage) {
$extW = imagesx($externalImage);
$extH = imagesy($externalImage);
$scale = max($width / $extW, $height / $extH);
$newW = (int)($extW * $scale);
$newH = (int)($extH * $scale);
$bg = imagecreatetruecolor($width, $height);
imagesavealpha($bg, true);
$transparent = imagecolorallocatealpha($bg, 0, 0, 0, 127);
imagefill($bg, 0, 0, $transparent);
imagecopyresampled($bg, $externalImage, (int)(($width - $newW)/2), (int)(($height - $newH)/2), 0, 0, $newW, $newH, $extW, $extH);
imagecopy($image, $bg, 0, 0, 0, 0, $width, $height);
imagedestroy($bg);
} else {
$bgType = mt_rand(0, 1);
if ($bgType === 0) {
do {
$bgColor = imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
} while ($bgColor === false);
imagefill($image, 0, 0, $bgColor);
} else {
$gradientColors = mt_rand(0, 1) ? 2 : 4;
$baseHue = mt_rand(0, 360);
$colors = [];
for ($i = 0; $i < $gradientColors; $i++) {
$hue = $baseHue + mt_rand(-15, 15);
$hue = max(0, min(360, $hue));
$colors[] = hslToRgb($hue / 360, mt_rand(80, 100) / 100, mt_rand(50, 80) / 100);
}
$directions = ['horizontal', 'vertical', 'diagonal', 'radial'];
$direction = $directions[array_rand($directions)];
createUltraGradient($image, $colors, $direction, $width, $height);
}
}
$hasCircles = (mt_rand(1, 10) === 1);
if ($hasCircles) {
$circleCount = mt_rand(3, 8);
for ($i = 0; $i < $circleCount; $i++) {
$circleColor = imagecolorallocatealpha($image, mt_rand(150, 255), mt_rand(150, 255), mt_rand(150, 255), mt_rand(30, 70));
$circleSize = mt_rand(40, min($width, $height) / 4);
$circleX = mt_rand(-$circleSize, $width + $circleSize);
$circleY = mt_rand(-$circleSize, $height + $circleSize);
imagefilledellipse($image, $circleX, $circleY, $circleSize, $circleSize, $circleColor);
}
}
$hasPattern = mt_rand(0, 3) === 0;
if ($hasPattern && !$externalImage) {
createGeometricPattern($image, $width, $height);
}
$processedText = $text;
if ($lang === 'fa') {
$chars = preg_split('//u', $text, -1, PREG_SPLIT_NO_EMPTY);
$reversed = array_reverse($chars);
$processedText = implode('', $reversed);
$rtlMarkers = "";
$processedText = $rtlMarkers . $processedText . $rtlMarkers;
}
$fontSize = calculateOptimalFontSize($processedText, $fontPath, $width, $height, $externalImage);
$angle = 0;
$bbox = imagettfbbox($fontSize, $angle, $fontPath, $processedText);
if ($bbox === false) {
createErrorImage('Error in calculating text size');
return;
}
$textWidth = $bbox[2] - $bbox[0];
$textHeight = $bbox[1] - $bbox[7];
$margin = 40;
if ($textWidth + $margin * 2 > $width) {
$scale = ($width - $margin * 2) / $textWidth;
$fontSize = max(12, (int)($fontSize * $scale));
$bbox = imagettfbbox($fontSize, $angle, $fontPath, $processedText);
$textWidth = $bbox[2] - $bbox[0];
$textHeight = $bbox[1] - $bbox[7];
}
$textX = ($width - $textWidth) / 2;
$textY = ($height - $textHeight) / 2 + $textHeight;
$textColor = null;
if ($externalImage) {
$avg = estimateAverageColor($image);
$lum = ($avg[0] * 0.299 + $avg[1] * 0.587 + $avg[2] * 0.114);
$textColor = $lum > 128 ? imagecolorallocate($image, 0, 0, 0) : imagecolorallocate($image, 255, 255, 255);
} else {
$textColor = imagecolorallocate($image, 255, 255, 255);
}
$hasShadow = false;
$hasGlow = false;
$hasBorder = false;
$hasTextGradient = false;
if ($hasShadow) {
$shadowIntensity = mt_rand(2, 4);
$shadowColor = imagecolorallocatealpha($image, 0, 0, 0, mt_rand(30, 60));
for ($i = 1; $i <= $shadowIntensity; $i++) {
imagettftext($image, $fontSize, $angle, $textX + $i, $textY + $i, $shadowColor, $fontPath, $processedText);
}
}
if ($hasGlow) {
$glowColor = imagecolorallocatealpha($image, mt_rand(100, 255), mt_rand(100, 255), mt_rand(100, 255), mt_rand(20, 40));
$glowSize = mt_rand(3, 6);
for ($i = -$glowSize; $i <= $glowSize; $i++) {
for ($j = -$glowSize; $j <= $glowSize; $j++) {
if (abs($i) + abs($j) <= $glowSize) {
imagettftext($image, $fontSize, $angle, $textX + $i, $textY + $j, $glowColor, $fontPath, $processedText);
}
}
}
}
if ($hasBorder) {
$borderColor = imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
$borderThickness = mt_rand(1, 3);
for ($i = -$borderThickness; $i <= $borderThickness; $i++) {
for ($j = -$borderThickness; $j <= $borderThickness; $j++) {
if (abs($i) + abs($j) <= $borderThickness * 1.5) {
imagettftext($image, $fontSize, $angle, $textX + $i, $textY + $j, $borderColor, $fontPath, $processedText);
}
}
}
}
imagettftext($image, $fontSize, $angle, (int)$textX, (int)$textY, $textColor, $fontPath, $processedText);
header('Content-Type: image/png');
imagepng($image, null, 9);
imagedestroy($image);
}
function calculateOptimalFontSize($text, $fontPath, $width, $height, $externalImage) {
$maxSize = min($width, $height) / 3;
$minSize = 24;
if ($externalImage) {
$maxSize = min($width, $height) / 5;
}
for ($size = $maxSize; $size >= $minSize; $size -= 1) {
$bbox = imagettfbbox($size, 0, $fontPath, $text);
if ($bbox === false) continue;
$textWidth = $bbox[2] - $bbox[0];
$textHeight = $bbox[1] - $bbox[7];
if ($textWidth < $width * 0.85 && $textHeight < $height * 0.6) {
return $size;
}
}
return $minSize;
}
function loadExternalImage($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
curl_setopt($ch, CURLOPT_ENCODING, '');
$imageData = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if (!$imageData || $httpCode !== 200) {
return null;
}
$image = @imagecreatefromstring($imageData);
if (!$image) {
return null;
}
return $image;
}
function makeImageRounded($image) {
$width = imagesx($image);
$height = imagesy($image);
$rounded = imagecreatetruecolor($width, $height);
imagesavealpha($rounded, true);
$transparent = imagecolorallocatealpha($rounded, 0, 0, 0, 127);
imagefill($rounded, 0, 0, $transparent);
$radius = min($width, $height) / 4;
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
$distance = sqrt(pow($x - $width/2, 2) + pow($y - $height/2, 2));
if ($distance <= $radius) {
$color = imagecolorat($image, $x, $y);
imagesetpixel($rounded, $x, $y, $color);
}
}
}
imagedestroy($image);
return $rounded;
}
function drawUltraGradientText($image, $text, $fontPath, $fontSize, $angle, $x, $y, $width, $height) {
$baseHue = mt_rand(0, 360);
$color1 = hslToRgb($baseHue / 360, 0.9, 0.6);
$color2 = hslToRgb(($baseHue + mt_rand(30, 120)) / 360, 0.9, 0.6);
$bbox = imagettfbbox($fontSize, $angle, $fontPath, $text);
if ($bbox === false) return;
$textWidth = $bbox[2] - $bbox[0];
$textHeight = $bbox[1] - $bbox[7];
$textImage = imagecreatetruecolor($textWidth, $textHeight);
imagesavealpha($textImage, true);
$transparent = imagecolorallocatealpha($textImage, 0, 0, 0, 127);
imagefill($textImage, 0, 0, $transparent);
$gradientType = mt_rand(0, 2);
if ($gradientType === 0) {
for ($i = 0; $i < $textWidth; $i++) {
$ratio = $i / $textWidth;
$r = $color1[0] + ($color2[0] - $color1[0]) * $ratio;
$g = $color1[1] + ($color2[1] - $color1[1]) * $ratio;
$b = $color1[2] + ($color2[2] - $color1[2]) * $ratio;
$color = imagecolorallocate($textImage, $r, $g, $b);
imageline($textImage, $i, 0, $i, $textHeight, $color);
}
} else {
for ($i = 0; $i < $textHeight; $i++) {
$ratio = $i / $textHeight;
$r = $color1[0] + ($color2[0] - $color1[0]) * $ratio;
$g = $color1[1] + ($color2[1] - $color1[1]) * $ratio;
$b = $color1[2] + ($color2[2] - $color1[2]) * $ratio;
$color = imagecolorallocate($textImage, $r, $g, $b);
imageline($textImage, 0, $i, $textWidth, $i, $color);
}
}
$maskColor = imagecolorallocate($textImage, 255, 255, 255);
imagettftext($textImage, $fontSize, $angle, 0, $bbox[1], $maskColor, $fontPath, $text);
imagecopymerge($image, $textImage, $x, $y - $bbox[1], 0, 0, $textWidth, $textHeight, 100);
imagedestroy($textImage);
}
function createUltraGradient($image, $colors, $direction, $width, $height) {
$colorCount = count($colors);
switch ($direction) {
case 'horizontal':
for ($i = 0; $i < $width; $i++) {
$ratio = $i / ($width - 1);
$colorIndex = $ratio * ($colorCount - 1);
$index1 = floor($colorIndex);
$index2 = min($index1 + 1, $colorCount - 1);
$fraction = $colorIndex - $index1;
$r = $colors[$index1][0] + ($colors[$index2][0] - $colors[$index1][0]) * $fraction;
$g = $colors[$index1][1] + ($colors[$index2][1] - $colors[$index1][1]) * $fraction;
$b = $colors[$index1][2] + ($colors[$index2][2] - $colors[$index1][2]) * $fraction;
$color = imagecolorallocate($image, $r, $g, $b);
imageline($image, $i, 0, $i, $height, $color);
}
break;
case 'vertical':
for ($i = 0; $i < $height; $i++) {
$ratio = $i / ($height - 1);
$colorIndex = $ratio * ($colorCount - 1);
$index1 = floor($colorIndex);
$index2 = min($index1 + 1, $colorCount - 1);
$fraction = $colorIndex - $index1;
$r = $colors[$index1][0] + ($colors[$index2][0] - $colors[$index1][0]) * $fraction;
$g = $colors[$index1][1] + ($colors[$index2][1] - $colors[$index1][1]) * $fraction;
$b = $colors[$index1][2] + ($colors[$index2][2] - $colors[$index1][2]) * $fraction;
$color = imagecolorallocate($image, $r, $g, $b);
imageline($image, 0, $i, $width, $i, $color);
}
break;
case 'diagonal':
for ($i = 0; $i < $width; $i++) {
for ($j = 0; $j < $height; $j++) {
$ratio = ($i + $j) / ($width + $height - 2);
$colorIndex = $ratio * ($colorCount - 1);
$index1 = floor($colorIndex);
$index2 = min($index1 + 1, $colorCount - 1);
$fraction = $colorIndex - $index1;
$r = $colors[$index1][0] + ($colors[$index2][0] - $colors[$index1][0]) * $fraction;
$g = $colors[$index1][1] + ($colors[$index2][1] - $colors[$index1][1]) * $fraction;
$b = $colors[$index1][2] + ($colors[$index2][2] - $colors[$index1][2]) * $fraction;
$color = imagecolorallocate($image, $r, $g, $b);
imagesetpixel($image, $i, $j, $color);
}
}
break;
case 'radial':
$centerX = $width / 2;
$centerY = $height / 2;
$maxRadius = sqrt($centerX * $centerX + $centerY * $centerY);
for ($i = 0; $i < $width; $i++) {
for ($j = 0; $j < $height; $j++) {
$dx = $i - $centerX;
$dy = $j - $centerY;
$distance = sqrt($dx * $dx + $dy * $dy);
$ratio = min(1, $distance / $maxRadius);
$colorIndex = $ratio * ($colorCount - 1);
$index1 = floor($colorIndex);
$index2 = min($index1 + 1, $colorCount - 1);
$fraction = $colorIndex - $index1;
$r = $colors[$index1][0] + ($colors[$index2][0] - $colors[$index1][0]) * $fraction;
$g = $colors[$index1][1] + ($colors[$index2][1] - $colors[$index1][1]) * $fraction;
$b = $colors[$index1][2] + ($colors[$index2][2] - $colors[$index1][2]) * $fraction;
$color = imagecolorallocate($image, $r, $g, $b);
imagesetpixel($image, $i, $j, $color);
}
}
break;
}
}
function createGeometricPattern($image, $width, $height) {
$patternType = mt_rand(0, 2);
$patternColor = imagecolorallocatealpha($image, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255), mt_rand(10, 30));
switch ($patternType) {
case 0:
for ($i = 0; $i < $width; $i += 20) {
imageline($image, $i, 0, $i, $height, $patternColor);
}
for ($i = 0; $i < $height; $i += 20) {
imageline($image, 0, $i, $width, $i, $patternColor);
}
break;
case 1:
for ($i = -$width; $i < $width * 2; $i += 30) {
imageline($image, $i, 0, $i + $height, $height, $patternColor);
}
break;
case 2:
$circleSpacing = min($width, $height) / 10;
for ($i = $circleSpacing; $i < $width; $i += $circleSpacing) {
for ($j = $circleSpacing; $j < $height; $j += $circleSpacing) {
imagefilledellipse($image, $i, $j, 8, 8, $patternColor);
}
}
break;
}
}
function addVignetteEffect($image, $width, $height) {
$centerX = $width / 2;
$centerY = $height / 2;
$maxDistance = sqrt($centerX * $centerX + $centerY * $centerY);
for ($i = 0; $i < $width; $i++) {
for ($j = 0; $j < $height; $j++) {
$dx = $i - $centerX;
$dy = $j - $centerY;
$distance = sqrt($dx * $dx + $dy * $dy);
$ratio = $distance / $maxDistance;
$vignette = imagecolorallocatealpha($image, 0, 0, 0, $ratio * 60);
imagesetpixel($image, $i, $j, $vignette);
}
}
}
function hslToRgb($h, $s, $l) {
$r = $l;
$g = $l;
$b = $l;
$v = ($l <= 0.5) ? ($l * (1.0 + $s)) : ($l + $s - $l * $s);
if ($v > 0) {
$m = $l + $l - $v;
$sv = ($v - $m) / $v;
$h *= 6.0;
$sextant = floor($h);
$fract = $h - $sextant;
$vsf = $v * $sv * $fract;
$mid1 = $m + $vsf;
$mid2 = $v - $vsf;
switch ($sextant) {
case 0:
$r = $v; $g = $mid1; $b = $m;
break;
case 1:
$r = $mid2; $g = $v; $b = $m;
break;
case 2:
$r = $m; $g = $v; $b = $mid1;
break;
case 3:
$r = $m; $g = $mid2; $b = $v;
break;
case 4:
$r = $mid1; $g = $m; $b = $v;
break;
case 5:
$r = $v; $g = $m; $b = $mid2;
break;
}
}
return [round($r * 255), round($g * 255), round($b * 255)];
}
function createErrorImage($message) {
$width = 500;
$height = 500;
$image = imagecreatetruecolor($width, $height);
$bgColor = imagecolorallocate($image, 255, 200, 200);
$textColor = imagecolorallocate($image, 255, 0, 0);
imagefill($image, 0, 0, $bgColor);
$font = 5;
$textWidth = imagefontwidth($font) * strlen($message);
$textHeight = imagefontheight($font);
$x = ($width - $textWidth) / 2;
$y = ($height - $textHeight) / 2;
imagestring($image, $font, $x, $y, $message, $textColor);
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
}
if (!function_exists('mb_str_split')) {
function mb_str_split($string, $length = 1) {
$result = [];
for ($i = 0; $i < mb_strlen($string); $i += $length) {
$result[] = mb_substr($string, $i, $length);
}
return $result;
}
}
function estimateAverageColor($image) {
$w = imagesx($image);
$h = imagesy($image);
$stepX = max(1, (int)($w / 10));
$stepY = max(1, (int)($h / 10));
$r = $g = $b = 0;
$count = 0;
for ($x = 0; $x < $w; $x += $stepX) {
for ($y = 0; $y < $h; $y += $stepY) {
$c = imagecolorat($image, $x, $y);
$r += ($c >> 16) & 0xFF;
$g += ($c >> 8) & 0xFF;
$b += $c & 0xFF;
$count++;
}
}
return [ (int)($r / $count), (int)($g / $count), (int)($b / $count) ];
}
function processPersianText($text) {
$normalized = normalizer_is_normalized($text, Normalizer::FORM_C) ? $text : normalizer_normalize($text, Normalizer::FORM_C);
if (function_exists('fribidi_log2vis')) {
$res = @fribidi_log2vis($normalized);
if ($res !== false && is_string($res)) {
return $res;
}
}
if (class_exists('IntlChar')) {
$rtlMarkers = "\xE2\x80\x8F";
return $rtlMarkers . $normalized;
}
return $normalized;
}
set_time_limit(300);
generateTextImage();
?>