首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP + Flash 頭像上傳組件實現:裁剪、多尺寸生成、Base64 傳輸完整方案

     編輯:PHP 綜合知識

架構概覽

┌──────────────┐     SWF 上傳      ┌─────────────┐     Base64 POST      ┌──────────┐
│  瀏覽器      │ ──────────────▶  │  Flash SWF  │ ──────────────────▶  │  PHP     │
│  加載 SWF    │   選圖/裁剪/縮放  │  裁剪預覽   │   pic/pic1/pic2/pic3  │  upfile.php │
└──────────────┘                  └─────────────┘                      └──────────┘
                                                                      │
                                                               生成 3 尺寸 PNG
                                                               返回 JSON 狀態

前端嵌入代碼

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Flash 頭像上傳</title>
<style>
html, body { height: 100%; background: #fff; margin: 0; }
#flashContent { width: 100%; height: 100%; }
#avatar_preview img { max-width: 120px; margin: 5px; border: 1px solid #ddd; }
</style>
<script>
function uploadCallback(status) {
    status += '';
    const preview = document.getElementById('avatar_preview');
    const ts = Date.now();
    
    switch (status) {
        case '1': // 成功
            preview.innerHTML = 
                "頭像1 (162px): <img src='1.png?" + ts + "'/><br>" +
                "頭像2 (48px): <img src='2.png?" + ts + "'/><br>" +
                "頭像3 (20px): <img src='3.png?" + ts + "'/>";
            break;
        case '-1': // 失敗/重試
        default:
            location.reload();
    }
}
</script>
</head>
<body>
<div id="altContent">
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
            codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0"
            width="650" height="450" id="avatarUploader">
        <param name="movie" value="avatar.swf" />
        <param name="quality" value="high" />
        <param name="bgcolor" value="#FFFFFF" />
        <param name="wmode" value="transparent" />
        <param name="allowScriptAccess" value="always" />
        <param name="flashvars" 
              value="imgUrl=./default.jpg&uploadUrl=./upfile.php&uploadSrc=false" />
        <embed src="avatar.swf" quality="high" bgcolor="#FFFFFF"
               width="650" height="450" wmode="transparent"
               flashvars="imgUrl=./default.jpg&uploadUrl=./upfile.php&uploadSrc=false"
               allowScriptAccess="always"
               type="application/x-shockwave-flash"
               pluginspage="https://www.adobe.com/go/getflashplayer">
        </embed>
    </object>
</div>
<div id="avatar_preview"></div>
</body>
</html>

PHP 接收端 upfile.php

<?php
header('Content-Type: application/json; charset=utf-8');

// 配置
$saveDir = __DIR__ . '/uploads/';
$maxSize = 5 * 1024 * 1024; // 5MB
$allowedMime = ['image/jpeg', 'image/png', 'image/gif'];

if (!is_dir($saveDir)) {
    mkdir($saveDir, 0755, true);
}

// 驗證請求
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    exit(json_encode(['status' => -1, 'msg' => 'Invalid method']));
}

// 解碼 Base64 圖片數據
$decode = function($key) use ($maxSize, $allowedMime) {
    if (empty($_POST[$key])) return false;
    $data = base64_decode($_POST[$key], true);
    if ($data === false || strlen($data) > $maxSize) return false;
    
    // 簡單 MIME 檢測
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $mime = $finfo->buffer($data);
    if (!in_array($mime, $allowedMime)) return false;
    
    return $data;
};

$src  = $decode('pic');   // 原圖
$pic1 = $decode('pic1');  // 162px
$pic2 = $decode('pic2');  // 48px
$pic3 = $decode('pic3');  // 20px

if (!$pic1 || !$pic2 || !$pic3) {
    exit(json_encode(['status' => -1, 'msg' => 'Invalid image data']));
}

// 保存文件
$timestamp = time();
$files = [
    'src'  => $saveDir . $timestamp . '_src.png',
    '162'  => $saveDir . $timestamp . '_162.png',
    '48'   => $saveDir . $timestamp . '_48.png',
    '20'   => $saveDir . $timestamp . '_20.png',
];

$success = true;
foreach ($files as $key => $path) {
    $data = ${$key} ?? null;
    if ($data && file_put_contents($path, $data) === false) {
        $success = false;
        break;
    }
}

if ($success) {
    echo json_encode([
        'status' => 1,
        'files'  => array_map(fn($p) => basename($p), $files)
    ]);
} else {
    // 回滾已寫入文件
    foreach ($files as $path) { @unlink($path); }
    echo json_encode(['status' => -1, 'msg' => 'Save failed']);
}
?>

關鍵技術點解析

技術點說明
Flash 繞過瀏覽器上傳限制可跨域、支持大文件、顯示進度條、客戶端裁剪
Base64 編碼傳輸Flash 將二進制圖片編碼為字符串 POST,避免 multipart 解析問題
客戶端多尺寸裁剪Flash 內部生成 162/48/20px 三套圖,服務端只存不處理
時間戳防緩存預覽圖 URL 加 ?timestamp 強制刷新

現代化替代方案(2024+ 推薦)

純 HTML5 + JavaScript 方案,無需 Flash:

  • Cropper.js:功能強大的圖片裁剪庫
  • File API + Canvas:客戶端壓縮、裁剪、預覽、Base64/Blob 上傳
  • WebUploader / Uppy:成熟的上傳組件,支持分片、斷點續傳
<!-- 現代 HTML5 版本片段 -->
<input type="file" id="avatarInput" accept="image/*" capture>
<canvas id="cropCanvas"></canvas>
<script src="cropper.min.js"></script>
<script>
// Cropper.js 初始化 + Canvas toBlob 上傳
</script>

遺留項目維護建議

  1. 保留 Flash 版本兼容老瀏覽器(IE8-)
  2. 新項目**嚴禁**使用 Flash(Adobe 2020 年底停止支持)
  3. 漸進式遷移:檢測 navigator.plugins['Shockwave Flash'] 決定加載哪套方案

Flash 曾是上傳裁剪的「瑞士軍刀」,如今已成歷史。新項目請擁抱 HTML5 生態。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved