diff --git a/includes/providers/class-open-router-image-provider.php b/includes/providers/class-open-router-image-provider.php index cc11203..c3acb06 100644 --- a/includes/providers/class-open-router-image-provider.php +++ b/includes/providers/class-open-router-image-provider.php @@ -222,11 +222,24 @@ class PRAutoBlogger_OpenRouter_Image_Provider implements PRAutoBlogger_Image_Pro * @param string $model Resolved model id. * @return array */ + /** + * Supported aspect ratios for OpenRouter image models (Gemini, GPT-5). + * Arbitrary ratios like 150:79 are rejected — must snap to one of these. + * + * @var array + */ + private const STANDARD_ASPECTS = [ + [ 'w' => 1, 'h' => 1, 'ratio' => 1.0 ], + [ 'w' => 3, 'h' => 2, 'ratio' => 1.5 ], + [ 'w' => 2, 'h' => 3, 'ratio' => 0.6667 ], + [ 'w' => 4, 'h' => 3, 'ratio' => 1.3333 ], + [ 'w' => 3, 'h' => 4, 'ratio' => 0.75 ], + [ 'w' => 16, 'h' => 9, 'ratio' => 1.7778 ], + [ 'w' => 9, 'h' => 16, 'ratio' => 0.5625 ], + ]; + private function build_request_body( string $prompt, int $width, int $height, string $model ): array { - $gcd = $this->support->gcd( $width, $height ); - $ar_w = (int) ( $width / $gcd ); - $ar_h = (int) ( $height / $gcd ); - $aspect = $ar_w . ':' . $ar_h; + $aspect = $this->snap_aspect_ratio( $width, $height ); return [ 'model' => $model, @@ -245,6 +258,30 @@ class PRAutoBlogger_OpenRouter_Image_Provider implements PRAutoBlogger_Image_Pro ]; } + /** + * Snap pixel dimensions to the nearest supported aspect ratio string. + * 1200×632 → ratio 1.8987 → nearest is 16:9 (1.7778). + * + * @param int $width Width in pixels. + * @param int $height Height in pixels. + * @return string Aspect ratio string like "16:9". + */ + private function snap_aspect_ratio( int $width, int $height ): string { + $target = $height > 0 ? (float) $width / (float) $height : 1.0; + $best = self::STANDARD_ASPECTS[0]; + $best_d = abs( $target - $best['ratio'] ); + + foreach ( self::STANDARD_ASPECTS as $candidate ) { + $d = abs( $target - $candidate['ratio'] ); + if ( $d < $best_d ) { + $best = $candidate; + $best_d = $d; + } + } + + return $best['w'] . ':' . $best['h']; + } + /** * Enforce the interface's dimension contract. *