210 lines
8.7 KiB
PHP
210 lines
8.7 KiB
PHP
<?php
|
|
// V179 wevia-brand · all providers masked as WEVIA Vision · internal_engine kept for debug
|
|
/**
|
|
* V176 · ambre-tool-image.php · Upgraded with quality cascade
|
|
* Yacine: "IMAGE POURRI MET A LOUVER QWEN IMAGE POUR AMELOIRER"
|
|
*
|
|
* Cascade (order by QUALITY):
|
|
* 1. Gemini 3 Pro Image Preview (best quality, free tier via GEMINI_KEY) - PRIMARY
|
|
* 2. Qwen-Image via DashScope (requires ALIBABA_KEY with credits)
|
|
* 3. Pollinations flux (free, 1024x1024)
|
|
* 4. Pollinations sana (free, 768x768 fast fallback)
|
|
*
|
|
* Keep backward compat: same response schema as before
|
|
*/
|
|
header("Content-Type: application/json; charset=utf-8");
|
|
set_time_limit(90);
|
|
|
|
$raw = file_get_contents("php://input");
|
|
$in = json_decode($raw, true) ?: $_POST ?: $_GET;
|
|
$prompt = trim($in["prompt"] ?? $in["q"] ?? "");
|
|
|
|
if (!$prompt) { echo json_encode(["error"=>"prompt required"]); exit; }
|
|
|
|
// Clean prompt (keep unicode)
|
|
$clean = preg_replace('/[^\p{L}\p{N}\s,.\-!?]/u', '', $prompt);
|
|
$clean = mb_substr(trim($clean), 0, 400);
|
|
|
|
// Load secrets
|
|
$secrets = [];
|
|
foreach (file("/etc/weval/secrets.env") ?: [] as $line) {
|
|
$line = trim($line);
|
|
if (!$line || $line[0] === "#" || strpos($line, "=") === false) continue;
|
|
list($k, $v) = explode("=", $line, 2);
|
|
$secrets[trim($k)] = trim($v, " \"'");
|
|
}
|
|
$GEMINI_KEY = $secrets["GEMINI_KEY"] ?? "";
|
|
$ALIBABA_KEY = $secrets["ALIBABA_KEY"] ?? "";
|
|
|
|
// File naming (shared across cascade)
|
|
$dir = "/var/www/html/generated";
|
|
if (!is_dir($dir)) @mkdir($dir, 0755, true);
|
|
$slug = preg_replace('/[^a-z0-9]+/', '-', strtolower($clean));
|
|
$slug = substr(trim($slug, "-"), 0, 50);
|
|
$ts = date("Ymd-His");
|
|
$rand = bin2hex(random_bytes(3));
|
|
|
|
$t0 = microtime(true);
|
|
$result = null;
|
|
|
|
// ========== TIER 1: Gemini 3 Pro Image Preview (best quality, free) ==========
|
|
if ($GEMINI_KEY) {
|
|
$gurl = "https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-image-preview:generateContent?key=" . $GEMINI_KEY;
|
|
$body = json_encode([
|
|
"contents" => [["parts" => [["text" => $clean]]]],
|
|
"generationConfig" => ["responseModalities" => ["IMAGE", "TEXT"]],
|
|
]);
|
|
$ctx = stream_context_create([
|
|
"http" => [
|
|
"method" => "POST",
|
|
"header" => "Content-Type: application/json\r\n",
|
|
"content" => $body,
|
|
"timeout" => 60,
|
|
"ignore_errors" => true,
|
|
],
|
|
]);
|
|
$resp = @file_get_contents($gurl, false, $ctx);
|
|
if ($resp) {
|
|
$d = @json_decode($resp, true);
|
|
if (isset($d["candidates"][0]["content"]["parts"])) {
|
|
foreach ($d["candidates"][0]["content"]["parts"] as $p) {
|
|
if (isset($p["inlineData"]["data"])) {
|
|
$mime = $p["inlineData"]["mimeType"] ?? "image/jpeg";
|
|
$ext = strpos($mime, "png") !== false ? "png" : "jpg";
|
|
$filename = "wevia-img-vision-{$slug}-{$ts}-{$rand}.{$ext}";
|
|
$path = "$dir/$filename";
|
|
$img = base64_decode($p["inlineData"]["data"]);
|
|
if ($img && strlen($img) > 5000) {
|
|
file_put_contents($path, $img);
|
|
$result = [
|
|
"success" => true,
|
|
"prompt" => $clean,
|
|
"url" => "https://weval-consulting.com/generated/$filename",
|
|
"size_kb" => round(strlen($img)/1024, 1),
|
|
"elapsed_ms" => round((microtime(true)-$t0)*1000),
|
|
"provider" => "WEVIA Vision (premium)",
|
|
"quality" => "premium",
|
|
"engine" => "wevia-vision-v1",
|
|
"internal_engine" => "gemini-3-pro",
|
|
];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ========== TIER 2: Qwen-Image via DashScope (if Gemini failed + ALIBABA_KEY) ==========
|
|
if (!$result && $ALIBABA_KEY) {
|
|
// Create async task
|
|
$submit_ctx = stream_context_create([
|
|
"http" => [
|
|
"method" => "POST",
|
|
"header" => "Authorization: Bearer $ALIBABA_KEY\r\nContent-Type: application/json\r\nX-DashScope-Async: enable\r\n",
|
|
"content" => json_encode([
|
|
"model" => "qwen-image",
|
|
"input" => ["prompt" => $clean],
|
|
"parameters" => ["size" => "1024*1024", "n" => 1],
|
|
]),
|
|
"timeout" => 15,
|
|
"ignore_errors" => true,
|
|
],
|
|
]);
|
|
$submit_resp = @file_get_contents("https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis", false, $submit_ctx);
|
|
$submit_d = @json_decode($submit_resp, true);
|
|
$task_id = $submit_d["output"]["task_id"] ?? "";
|
|
if ($task_id) {
|
|
// Poll
|
|
for ($i = 0; $i < 20; $i++) {
|
|
sleep(2);
|
|
$pctx = stream_context_create(["http"=>["header"=>"Authorization: Bearer $ALIBABA_KEY\r\n","timeout"=>10]]);
|
|
$pr = @file_get_contents("https://dashscope-intl.aliyuncs.com/api/v1/tasks/$task_id", false, $pctx);
|
|
$pd = @json_decode($pr, true);
|
|
$status = $pd["output"]["task_status"] ?? "";
|
|
if ($status === "SUCCEEDED") {
|
|
$img_url = $pd["output"]["results"][0]["url"] ?? "";
|
|
if ($img_url) {
|
|
$img = @file_get_contents($img_url);
|
|
if ($img && strlen($img) > 5000) {
|
|
$filename = "wevia-img-vision-{$slug}-{$ts}-{$rand}.png";
|
|
$path = "$dir/$filename";
|
|
file_put_contents($path, $img);
|
|
$result = [
|
|
"success" => true,
|
|
"prompt" => $clean,
|
|
"url" => "https://weval-consulting.com/generated/$filename",
|
|
"size_kb" => round(strlen($img)/1024, 1),
|
|
"elapsed_ms" => round((microtime(true)-$t0)*1000),
|
|
"provider" => "WEVIA Vision (premium)",
|
|
"quality" => "premium",
|
|
"engine" => "wevia-vision-v1",
|
|
"internal_engine" => "qwen-image",
|
|
];
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
if ($status === "FAILED" || $status === "UNKNOWN") break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ========== TIER 3: Pollinations flux (free 1024x1024) ==========
|
|
if (!$result) {
|
|
$seed = rand(1, 99999);
|
|
$encoded = urlencode($clean);
|
|
// Try with flux model hint (even though list shows only sana, try anyway)
|
|
$flux_url = "https://image.pollinations.ai/prompt/$encoded?width=1024&height=1024&seed=$seed&nologo=true&enhance=true&model=flux";
|
|
$ctx2 = stream_context_create(["http"=>["timeout"=>30,"header"=>"User-Agent: WEVIA/2.0\r\n"]]);
|
|
$img = @file_get_contents($flux_url, false, $ctx2);
|
|
if ($img && strlen($img) > 5000) {
|
|
$filename = "wevia-img-vision-{$slug}-{$ts}-{$rand}.jpg";
|
|
$path = "$dir/$filename";
|
|
file_put_contents($path, $img);
|
|
$result = [
|
|
"success" => true,
|
|
"prompt" => $clean,
|
|
"url" => "https://weval-consulting.com/generated/$filename",
|
|
"size_kb" => round(strlen($img)/1024, 1),
|
|
"elapsed_ms" => round((microtime(true)-$t0)*1000),
|
|
"provider" => "WEVIA Vision (standard)",
|
|
"quality" => "standard",
|
|
"engine" => "wevia-vision-v1",
|
|
"internal_engine" => "pollinations-flux",
|
|
];
|
|
}
|
|
}
|
|
|
|
// ========== TIER 4: Pollinations sana (last resort) ==========
|
|
if (!$result) {
|
|
$seed = rand(1, 99999);
|
|
$encoded = urlencode($clean);
|
|
$sana_url = "https://image.pollinations.ai/prompt/$encoded?width=1024&height=1024&seed=$seed&nologo=true&enhance=true";
|
|
$ctx3 = stream_context_create(["http"=>["timeout"=>30,"header"=>"User-Agent: WEVIA/2.0\r\n"]]);
|
|
$img = @file_get_contents($sana_url, false, $ctx3);
|
|
if ($img && strlen($img) > 5000) {
|
|
$filename = "wevia-img-vision-{$slug}-{$ts}-{$rand}.jpg";
|
|
$path = "$dir/$filename";
|
|
file_put_contents($path, $img);
|
|
$result = [
|
|
"success" => true,
|
|
"prompt" => $clean,
|
|
"url" => "https://weval-consulting.com/generated/$filename",
|
|
"size_kb" => round(strlen($img)/1024, 1),
|
|
"elapsed_ms" => round((microtime(true)-$t0)*1000),
|
|
"provider" => "WEVIA Vision (basic)",
|
|
"quality" => "basic",
|
|
"engine" => "wevia-vision-v1",
|
|
"internal_engine" => "pollinations-sana",
|
|
];
|
|
}
|
|
}
|
|
|
|
if (!$result) {
|
|
echo json_encode(["error"=>"all image providers failed","prompt"=>$clean]);
|
|
exit;
|
|
}
|
|
|
|
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|