소스 검색

Merge branch 'hsposter' into dev

shish 2 달 전
부모
커밋
cb21b25517
2개의 변경된 파일104개의 추가작업 그리고 6개의 파일을 삭제
  1. 72 6
      common/components/PosterUtil.php
  2. 32 0
      common/components/imgUtil.php

+ 72 - 6
common/components/PosterUtil.php

@@ -3,14 +3,31 @@
 namespace common\components;
 
 /**
- * 散客分享海报(OSS 图片水印合成)
+ * 散客分享海报(OSS:poster/blank.png 动态画布 + 水印合成)
  */
 class PosterUtil
 {
-    const BASE_TEMPLATE = 'poster/1234.jpg';
+    /** 与 poster/1234.jpg 同目录的 10×10 白底,经 m_pad 拉成本次海报画布 */
+    const BLANK_CANVAS = 'poster/blank.png';
 
     const FONT = 'd3F5LW1pY3JvaGVp';
 
+    const POSTER_W = 750;
+
+    const SLOT_W = 700;
+
+    const FOOTER_H = 360;
+
+    const IMG_H_MIN = 480;
+
+    const IMG_H_MAX = 880;
+
+    const TOTAL_H_MIN = 840;
+
+    const TOTAL_H_MAX = 1600;
+
+    const CANVAS_COLOR = 'FFFFFF';
+
     /**
      * 海报标题过长时截断,避免压住底部文案区
      */
@@ -26,6 +43,45 @@ class PosterUtil
         return $text;
     }
 
+    /**
+     * 按商品图比例计算主图区高度与画布总高
+     *
+     * @return array{imgH:int,totalH:int,posterW:int}
+     */
+    public static function calcPosterLayout($coverWidth, $coverHeight)
+    {
+        $coverWidth = (int)$coverWidth;
+        $coverHeight = (int)$coverHeight;
+
+        if ($coverWidth > 0 && $coverHeight > 0) {
+            $scaledH = (int)round($coverHeight * (self::SLOT_W / $coverWidth));
+            $imgH = max(self::IMG_H_MIN, min(self::IMG_H_MAX, $scaledH));
+        } else {
+            $imgH = 720;
+        }
+
+        $totalH = $imgH + self::FOOTER_H;
+        $totalH = max(self::TOTAL_H_MIN, min(self::TOTAL_H_MAX, $totalH));
+
+        return [
+            'imgH' => $imgH,
+            'totalH' => $totalH,
+            'posterW' => self::POSTER_W,
+        ];
+    }
+
+    /**
+     * 动态白底画布(blank.png → 750 × totalH)
+     */
+    public static function buildCanvasBaseUrl($prefix, $totalH)
+    {
+        $totalH = max(self::TOTAL_H_MIN, min(self::TOTAL_H_MAX, (int)$totalH));
+        $process = '?x-oss-process=image/resize,m_pad,w_' . self::POSTER_W . ',h_' . $totalH
+            . ',color_' . self::CANVAS_COLOR;
+
+        return $prefix . self::BLANK_CANVAS . $process;
+    }
+
     /**
      * 和炫鲜花等门店角标
      */
@@ -53,7 +109,7 @@ class PosterUtil
     }
 
     /**
-     * 花材海报(与花束同一套版式
+     * 花材海报(商城散客
      */
     public static function buildMallItemPosterUrl($prefix, array $options)
     {
@@ -72,7 +128,7 @@ class PosterUtil
     }
 
     /**
-     * 散客分享海报:主图 m_lfit、价格/标题/推荐人层次、扫码提示
+     * 散客/花束分享海报:动态画布 + 主图固定槽位 + 底部信息区
      */
     private static function buildMallSharePosterUrl($prefix, array $options)
     {
@@ -86,6 +142,16 @@ class PosterUtil
         $subtitle = trim((string)($options['subtitle'] ?? ''));
         $scanHint = trim((string)($options['scanHint'] ?? '微信扫码下单'));
 
+        $coverW = (int)($options['coverWidth'] ?? 0);
+        $coverH = (int)($options['coverHeight'] ?? 0);
+        if ($coverW <= 0 || $coverH <= 0) {
+            list($coverW, $coverH) = imgUtil::getOssImageSize($cover, $prefix);
+        }
+
+        $layout = self::calcPosterLayout($coverW, $coverH);
+        $imgH = $layout['imgH'];
+        $totalH = $layout['totalH'];
+
         $displayName = self::truncateText($name, 14);
         if ($flowerNum > 0 && $displayName !== '') {
             $displayName .= ' · ' . $flowerNum . '支';
@@ -93,10 +159,10 @@ class PosterUtil
             $displayName .= ' · ' . self::truncateText($subtitle, 8);
         }
 
-        $coverWatermark = $cover . '?x-oss-process=image/resize,m_lfit,h_1020,w_700,limit_0';
+        $coverWatermark = $cover . '?x-oss-process=image/resize,m_fill,h_' . $imgH . ',w_' . self::SLOT_W;
         $qrWatermark = $miniCode . '?x-oss-process=image/resize,m_fill,h_220,w_220';
 
-        $url = $prefix . self::BASE_TEMPLATE . '?x-oss-process=image';
+        $url = self::buildCanvasBaseUrl($prefix, $totalH);
         $url .= '/watermark,image_' . stringUtil::ossBase64($coverWatermark) . ',g_north,x_25,y_8';
         $url .= '/watermark,image_' . stringUtil::ossBase64($qrWatermark) . ',g_se,x_36,y_32';
 

+ 32 - 0
common/components/imgUtil.php

@@ -52,4 +52,36 @@ class imgUtil
         return $pic;
     }
 
+    /**
+     * 通过 OSS image/info 读取图片宽高(用于海报动态画布)
+     *
+     * @return array{0:int,1:int} [width, height]
+     */
+    public static function getOssImageSize($objectPath, $prefix = null)
+    {
+        $objectPath = self::normalizeOssObjectPath($objectPath);
+        if ($prefix === null || $prefix === '') {
+            $prefix = self::getPrefix();
+        }
+        $infoUrl = rtrim($prefix, '/') . '/' . $objectPath . '?x-oss-process=image/info';
+        $context = stream_context_create([
+            'http' => [
+                'timeout' => 5,
+                'ignore_errors' => true,
+            ],
+        ]);
+        $json = @file_get_contents($infoUrl, false, $context);
+        if ($json === false || $json === '') {
+            return [0, 0];
+        }
+        $data = json_decode($json, true);
+        if (!is_array($data)) {
+            return [0, 0];
+        }
+        $w = (int)($data['ImageWidth']['value'] ?? 0);
+        $h = (int)($data['ImageHeight']['value'] ?? 0);
+
+        return [$w, $h];
+    }
+
 }