Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
以圖搜圖系統開發技術分享
Search
滋滋桑
August 04, 2026
17
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
以圖搜圖系統開發技術分享
滋滋桑
August 04, 2026
More Decks by 滋滋桑
See All by 滋滋桑
碳足跡_python.pdf
tzutzu
0
13
使用JavaScript製作互動式網頁導覽列
tzutzu
0
25
Laravel 8 的使用方式
tzutzu
0
31
SPRING BOOT+VUE+資料庫到底是甚麼
tzutzu
0
77
asp.net用北風資料庫來說明實用技術
tzutzu
0
130
資料庫是什麼
tzutzu
0
50
如何準備證照考試
tzutzu
0
120
準備面試
tzutzu
0
390
Featured
See All Featured
The Cult of Friendly URLs
andyhume
79
7k
Amusing Abliteration
ianozsvald
1
290
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
4
590
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
Facilitating Awesome Meetings
lara
57
7.1k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Code Review Best Practice
trishagee
74
20k
Context Engineering - Making Every Token Count
addyosmani
9
1.1k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
600
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
200
Transcript
以以以以以以 以以以以以以 TZU FB-29歲女生學程式
研究以圖搜圖:目標像蝦皮
找相似
以以以以以以以以以 Image Upload & Hash Processing Logic Controller 以以以以 •
圖片檔案接收與驗證 檔案格式檢查 大小限制控制 • 圖片儲存處理 本地儲存路徑設定 檔名重新命名機制 • DifferenceHash 演算法 圖片縮放與灰階轉換 差異值計算生成雜湊
以以以以以以以以以 Similar Image Search Algorithm • 以以以以以以 × (Hamming Distance
Calculation) 比較兩個雜湊值之間的位元差異數量 • 以以以以以 (Threshold Configuration) 設定相似度判定的臨界值節因 • 以以以以以 (Database Filtering Logic) 以以以以以 以 根據計算結果篩選出相似圖片候選 以以以以以以以以以以以以以 以以以以以以以以以以以以 以
API 以以以以以以以以以 Backend API Configuration & Postman Testing API 以以以以
Postman 以以以以 • 後後後後後後後後 • 後後後後後後後後 • RESTful API 後後後後 • 後後後後後後後後後 • 後後後後後後後後後 • API 後後後後後後 Postman API 後後後後後後
帶您讀源碼 •
先用自己的環境測試 測試下載套件: 針對 Laravel 8 使用圖像相 似度搜索功能的每一步詳細操作流程,以 jenssegers/imagehash 套件
在VS CODE的地方 選終端機:新終端機 下方終端機執行:
確保已安裝 Laravel 8 環境: bash composer create-project --prefer-dist laravel/laravel="8.*" laravel-image-search
安裝圖片哈希套件: bash composer require jenssegers/imagehash
如果版本太舊,可以嘗試更新到較新的版本(在 Laravel 8 相容的範圍內): composer update jenssegers/imagehash
下方終端機執行: bash 會產生當天的日期在 migration php artisan make:migration create_images_table --create=images
帶您讀源碼 •
帶您讀源碼-會產生當天的日期在 migrations/2025_08_29_create_images_table.php 這段程式碼是一個 Laravel migration,作用是建立 imagetwo 資料表,並定義欄位 結構;其中 up() 負責建立表,
down() 負責回滾時刪除表。程 式碼用途 CreateImagetwoTable 繼承 Migration,表示它是資料庫版本 控制的一部分,通常會配合 php artisan migrate 執行。 當 migration 執行時, Schema::create('imagetwo', ...) 會建立名為 imagetwo 的資料表。
• 帶您讀源碼• php • <?php • PHP 檔案開頭,告訴伺服器這是一個 PHP 檔
案。 • php • use Illuminate\Database\Migrations\Migration; • 引入 Laravel 的 Migration 基底類別,這個 migration 會繼承它,讓 Laravel 知道怎麼處理 建表、刪表等操作。
• 帶您讀源碼• php • use Illuminate\Database\Schema\Blueprint; • 引入 Blueprint 類別,這是用來「描述資料表結構」的物件,像是你在
Schema::create(...) 裡面那個匿名函數裡用到的 $table。 • php • use Illuminate\Support\Facades\Schema; • 引入 Schema 外觀(Facade),用來呼叫 Schema::create()、 Schema::dropIfExists() 這些方法,方便操作資料庫結構。
• 帶您讀源碼• php • class CreateImagetwoTable extends Migration • 宣告一個類別
CreateImagetwoTable,繼承 Laravel 的 Migration,Laravel 會透過檔名判斷這是用來建立 imagetwo 表的 migration。 • php • { • 開始類別區塊。 • php • /** • * Run the migrations. • * • * @return void • */ • 這是 PHPDoc 註解
帶您讀源碼下方 up() 方法是「執行遷移」時會被呼叫的函式,用來改變資料庫結 構(例如建表、加欄位)。 php public function up() { up()
方法:當你執行 php artisan migrate 時,會呼叫這個方法,用來 「向前」建立或修改資料表。 php /*Schema::create('imagetwo', function (Blueprint $table) { $table->id(); $table->timestamps(); });*/ 這部分是被註解掉的舊版本,原本是只要建立 imagetwo 表,只包含 id 和自動時間戳欄位,但目前不會被執行。
帶您讀源碼php Schema::create('imagetwo', function (Blueprint $table) { 呼叫 Schema::create(), 第一個參數 'imagetwo'
是要建立的資料表名稱, 第二個是匿名函數,用來定義這張表的欄位。 php $table->id(); 在 Blueprint 物件上呼叫 id(),會自動建立一個主鍵欄位, 預設名字是 id, 型別通常是 BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, 用來唯一標示每一筆資料。
帶您讀源碼php $table->string('path'); 建立一個字串欄位 path,預設是 VARCHAR,用途通常是存圖片 的檔案路徑(例如:/uploads/2026/05/01.jpg)。 這欄位是必填的,因為沒有加 nullable(),新增資料時一定要提供 路徑值。 php
$table->string('image_hash')->nullable(); 再建立一個欄位 image_hash,也是字串(VARCHAR),但加上 nullable(),表示這欄位可以為 NULL(也就是可以不填)。 實務上通常用來存圖片的雜湊值(如 md5 或 sha256),方便做重 複圖片判斷、內容比對、快取或防竄改。
帶您讀源碼php $table->timestamps(); 建立 Laravel 內建的兩個時間戳欄位:created_at 和 updated_at,用來自動記錄資料的建立時間與最後更新時間。 只要 Model 有繼承
Model,這些欄位會自動被填入時間。 php }); 結束 Schema::create() 的匿名函數和區塊,也就是「資料表結 構描述」到這邊結束。 php } 結束 public function up() 方法。
帶您讀源碼php /** * Reverse the migrations. * * @return void
*/ 這是 PHPDoc 註解,說明下面的 down() 方法是在「回滾遷移」時會 被呼叫的方法,用來還原 up() 做的變更。 php public function down() { down() 方法:當你執行 php artisan migrate:rollback 或 migrate:reset 時會被呼叫,用來「向後」還原資料庫結構。
帶您讀源碼php Schema::dropIfExists('imagetwo'); 呼叫 Schema::dropIfExists(),刪除名為 imagetwo 的資 料表。 dropIfExists 會先檢查表是否存在,如果存在再刪除,避 免已經刪除卻再刪一次造成錯誤。
php } 結束 public function down() 方法。 php } 結束整個 CreateImagetwoTable 類別。
帶您讀源碼-會產生當天的日期在 migrations/2025_08_29_create_images_table.php 這段程式碼是一個 Laravel migration,作用是建立 imagetwo 資料表,並定義欄位 結構;其中 up() 負責建立表,
down() 負責回滾時刪除表。程 式碼用途 CreateImagetwoTable 繼承 Migration,表示它是資料庫版本 控制的一部分,通常會配合 php artisan migrate 執行。 當 migration 執行時, Schema::create('imagetwo', ...) 會建立名為 imagetwo 的資料 表。
到在VS CODE的地方選終端機:新終端機 下方終端機執行 Migration: bash php artisan migrate 總結 這支
migration 做了一件很簡單但必要的事: 「建立一張 imagetwo 表,用來存圖片路徑和可選的圖片 雜湊,並提供回滾機制,必要時可以刪除這張表」。
產生的資料表
在VS CODE的地方選終端機:新終端機 下方終端機執行:建立 Image 模型 bash php artisan make:model Image
帶您讀源碼 •
資料結構的建立SQL: CREATE TABLE `imagetwo` ( `id` bigint unsigned NOT NULL
AUTO_INCREMENT, `path` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `image_hash` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
帶您讀源碼<?php 這是 PHP 檔案的開頭,表示這份檔案要用 PHP 語法來執行。 php namespace App\Models; 這行宣告命名空間是
App\Models,表示這個 ImageTwo 類別屬於 Laravel 專案中的 Model 目錄結構。 Laravel 預設會把 Eloquent Model 放在 app/Models 底下,所以這樣 寫符合框架慣例。 php use Illuminate\Database\Eloquent\Factories\HasFactory; 這行引入 HasFactory trait,讓這個 Model 可以搭配 Laravel 的 Factory 功能使用,通常是拿來做測試資料或假資料產生。 它不是直接拿來連資料庫,而是之後可以方便地建立 model factory。
帶您讀源碼php use Illuminate\Database\Eloquent\Model; 這行引入 Laravel 的 Model 基底類別,因為你的 ImageTwo 要繼承它,才能具有
Eloquent ORM 的功 能,例如查詢、新增、更新、刪除資料。 php class ImageTwo extends Model 這行宣告一個類別 ImageTwo,並讓它繼承 Model。 這代表 ImageTwo 會對應到一張資料表,並可以使用像 ImageTwo::all()、ImageTwo::create() 這類 Eloquent 操 作。
帶您讀源碼php { 這是類別內容的開始。 php use HasFactory; 這行把 HasFactory trait 放進
ImageTwo 類別中,讓這個 model 支援工廠功能。 之後有建立 ImageTwoFactory,就可以透過這個 model 快速產 生測試資料。 php protected $table = 'imagetwo'; // 指定資料表名稱
帶您讀源碼php protected $fillable = ['path', 'image_hash']; 這行設定「可大量指定的欄位」,也就是當你使用 create()、fill() 這些方法時,只允許 path
和 image_hash 被批次寫入 php } 這是 ImageTwo 類別的結束。 程式碼整體意思 這個 Model 的作用是:把 ImageTwo 這個 PHP 類別,對應到 資料庫裡的 imagetwo 表,並允許 path 與 image_hash 兩個欄 位透過 Eloquent 直接新增或更新
建立 Controller(也可以用手動新增) 到在VS CODE的地方選終端機:新終端機 下方終端機執行 bash php artisan make:controller ImageController
圖片存放的地方 (之後再以公司存放的位置調整)
帶您讀源碼 •
帶您讀源碼這支 ImageTwoController.php 是一個 Laravel 控制器,主要做兩件 事:上傳圖片並存資料,以及拿一張圖片去搜尋相似圖片。 它也另外寫了一個私有方法,用來在某些情況下手動計算兩個 hash 的漢明距離。類別與引用 php
<?php 這是 PHP 檔案開頭,表示接下來的內容使用 PHP 語法。 php namespace App\Http\Controllers; 宣告這個類別位於 App\Http\Controllers 命名空間,也就是 Laravel 專案中控制器的標準位置。
帶您讀源碼php use Illuminate\Http\Request; 引入 Request 類別,用來接收前端送來的 HTTP 請求資料, 例如上傳的圖片檔案。 php
use App\Models\ImageTwo; 引入你前面建立的 ImageTwo model,讓控制器可以把圖片 資訊寫入資料庫,或從資料庫讀出已存圖片資料。 php use Jenssegers\ImageHash\ImageHash; 引入 ImageHash 類別,這個套件用來計算圖片的感知雜湊值, 也就是不是單純看檔案位元,而是根據圖片視覺特徵產生 hash。
帶您讀源碼php use Jenssegers\ImageHash\Implementations\DifferenceHash; 引入 DifferenceHash 演算法,這是 jenssegers/imagehash 套 件支援的一種感知雜湊方式,常用來做相似圖片比較。php class
ImageTwoController extends Controller 宣告 ImageTwoController 類別,並繼承 Laravel 基底控制器 Controller,表示這是一支處理請求邏輯的控制器。php { 開始類別區塊。
帶您讀源碼-upload 方法 php // 上傳圖片並存資料 public function upload(Request $request) 這是一個公開方法
upload,接收 $request 物件,功能是處理圖片上 傳。 php { $request->validate([ 'image' => 'required|image|max:2048', ]); 這裡先做驗證,要求請求中一定要有 image 欄位,而且必須是圖片 檔,大小不能超過 2048 KB,也就是 2MB
帶您讀源碼如果驗證失敗,在 Laravel 的 情境下通常會直接回傳驗證錯誤的 JSON 回應。 \Log::info('開始上傳流程'); 寫一筆資訊等級的 log,表示程式開始執行上傳流程。 這對除錯很有幫助,方便你在
log 檔中追蹤流程走到哪一步。 try { 開始 try 區塊,代表接下來如果有例外錯誤,就會跳到後面的 catch 去處理。
帶您讀源碼if (!$request->hasFile('image')) { 再次確認請求中是否真的有收到檔案。 雖然前面已做驗證,但這裡又補一層保護,避免實際執行時沒有 檔案物件可用。 \Log::error('上傳失敗:沒有收到圖片'); 如果沒收到檔案,就記錄錯誤 log。 return
response()->json(['error' => '未收到圖片'], 400); 回傳 JSON 格式錯誤訊息,HTTP 狀態碼是 400,表示這是用戶 端請求有問題。 } 結束 if 判斷。
帶您讀源碼$hasher = new ImageHash(new DifferenceHash()); 建立一個圖片 hash 工具物件,並指定它使用 DifferenceHash 演算
法。 $hash = $hasher->hash($fullPath)->toHex(); 對剛上傳的圖片計算感知 hash,然後轉成十六進位字串儲存。 toHex() 的目的是把 hash 變成容易存進資料庫的字串格式。 \Log::info('圖片hash: ' . $hash); 把算出的 hash 寫進 log,方便比對與除錯。
帶您讀源碼php $image = ImageTwo::create([ 'path' => $path, 'image_hash' => $hash,
]); 透過 ImageTwo model 新增一筆資料到 imagetwo 資料表,寫入 圖片路徑與 hash。 這裡能直接 create(),是因為 model 已經在 $fillable 裡允許 path 和 image_hash 被指定。
帶您讀源碼\Log::info('資料庫寫入: ', $image->toArray()); 把剛寫入資料庫後的 model 內容轉成陣列,再寫入 log。 這樣可以確認資料是否真的成功新增。 return response()->json([
'message' => '圖片上傳成功', 'image' => $image, ]); 如果一切成功,就回傳 JSON,內容包含成功訊息與剛建立好的圖片 資料。 這通常會讓前端拿到新增後的 id、path、image_hash 等欄位資料。
帶您讀源碼} catch (\Exception $e) { 如果上面流程任何地方丟出例外,就會進到這個 catch。 \Log::error('圖片上傳錯誤: ' .
$e->getMessage()); 把例外錯誤訊息寫到 log,方便查問題。 return response()->json(['error' => '圖片上傳失敗'], 500); 回傳 JSON 錯誤訊息,HTTP 狀態碼 500,表示伺服器處理失敗。 php } } 結束 upload() 方法。
帶您讀源碼-search 方法 // 搜尋相似圖片 public function search(Request $request) 這是一個公開方法 search,接收上傳來的查詢圖片,用來找資
料庫中相似的圖片。 { $request->validate([ 'image' => 'required|image|max:2048', ]); 和 upload() 一樣,先驗證請求必須包含圖片,而且大小不能超 過 2MB。
帶您讀源碼try { 開始例外處理區塊。 if (!$request->hasFile('image')) { 再次確認是否真的有收到檔案。 \Log::error('搜尋失敗:未收到搜尋圖片'); 如果沒有,就記錄錯誤 log。
return response()->json(['error' => '未收到搜尋圖片'], 400); 回傳 400 錯誤,告訴前端沒有收到圖片檔。
帶您讀源碼} 結束這段判斷。 $tempPath = $request->file('image')->store('temp_images', 'public'); 把查詢用的圖片先暫存到 public 磁碟下的 temp_images
目錄。 這張圖片不是正式上傳保存,而是暫時拿來算 hash 和比對。 \Log::info('搜尋暫存圖片路徑:' . $tempPath); 把暫存圖片路徑寫到 log。 $fullTempPath = storage_path('app/public/' . $tempPath); 把暫存圖片的相對路徑轉成完整檔案路徑,給 hash 套件使用。
帶您讀源碼$hasher = new ImageHash(new DifferenceHash()); 建立一個 ImageHash 物件,仍然使用 DifferenceHash 演算法。
$searchHash = $hasher->hash($fullTempPath); 對查詢圖片計算感知 hash,不過這次先保留為 hash 物件,而 不是直接轉十六進位字串。 這樣後面可以直接拿來做距離比較。 $threshold = 10; // 相似偵測門檻距離,可調整 設定相似判斷門檻為 10。 一般來說,hash 距離越小表示越相似,所以只要距離小於 10, 就會被視為相似候選圖片。
帶您讀源碼php $path = $request->file('image')->store('imagetwo_images', 'public'); 從請求中取出 image 檔案,並把它存到 public 磁碟的
imagetwo_images 目錄下。 這行執行後,$path 會拿到實際儲存路徑字串,例如 imagetwo_images/xxxx.jpg。 \Log::info('存檔路徑: ' . $path); 把剛剛存檔後的相對路徑寫入 log,方便確認檔案到底存到哪裡。 $fullPath = storage_path('app/public/' . $path); 把相對路徑轉成伺服器上的完整實體路徑。 因為後面的圖片 hash 套件通常需要吃真實檔案路徑,不能只給資料庫 用的相對字串。
帶您讀源碼$candidates = ImageTwo::all()->filter(function ($image) use ($searchHash, $hasher, $threshold) { 先把資料表中的所有
ImageTwo 資料取出,再用 filter() 篩選符合條件的圖片。 這表示目前的做法是在 PHP 記憶體中逐筆比對,不是在 SQL 端做比對。 if (!$image->image_hash) { return false; } 如果某筆圖片沒有 image_hash,就直接排除,不參加相 似度比較。
帶您讀源碼try { 開始對單筆資料做安全比較,避免其中某一筆壞資料讓整個 搜尋中斷。 if (method_exists($hasher, 'hashFromHex')) { 先檢查 $hasher
物件有沒有 hashFromHex 這個方法。 這是為了兼容不同版本或不同情況的套件功能。 $storedHash = $hasher>hashFromHex($image->image_hash); 如果有 hashFromHex,就把資料庫裡儲存的十六進位字串 hash 還原成 hash 物件。
帶您讀源碼這樣就能和 $searchHash 做標準距離比較。 $distance = $searchHash>distance($storedHash); 直接計算查詢圖片 hash 與資料庫中該筆圖片 hash
的距離。 距離越小,代表兩張圖片越相似。 } else { 如果套件沒有 hashFromHex,就走備用方案。 $searchHex = $searchHash->toHex(); 先把查詢圖片的 hash 物件轉成十六進位字串。
以以以以以以以以以 Similar Image Search Algorithm • 以以以以以以 × (Hamming Distance
Calculation) 比較兩個雜湊值之間的位元差異數量 • 以以以以以 (Threshold Configuration) 設定相似度判定的臨界值節因 • 以以以以以 (Database Filtering Logic) 以以以以以 以 根據計算結果篩選出相似圖片候選 以以以以以以以以以以以以以 以以以以以以以以以以以以 以
帶您讀源碼$distance = $this>calculateHammingDistance($searchHex, $image->image_hash); 呼叫自己寫的 calculateHammingDistance() 方法,手動計算兩個十六進 位字串的漢明距離。 } 結束標準方案與備用方案的分支判斷。
\Log::info("圖片 {$image->id} 距離: {$distance}"); 把目前這筆圖片與查詢圖的距離記錄到 log,方便你觀察每一張圖的相似 度。 return $distance < $threshold; 如果距離小於門檻值 10,就保留這張圖;否則過濾掉。
帶您讀源碼- } catch (\Exception $e) { 如果單筆資料在比對過程中出錯,就進到這裡。 \Log::error("計算距離錯誤 (圖片 {$image->id}):
" . $e>getMessage()); 記錄是哪一張圖片出錯,以及錯誤訊息。 return false; 出錯的資料直接排除,不影響整體搜尋流程。 } 結束內層 try-catch。
帶您讀源碼})->values(); filter() 完成後,用 values() 重新整理索引,讓回傳集合變成連續索引的陣列 形式。 \Log::info('找到相似圖片數量:' . count($candidates)); 把找到幾張相似圖片記錄到
log。 if (file_exists($fullTempPath)) { unlink($fullTempPath); } 搜尋完成後,檢查暫存圖片檔案是否存在;如果存在就刪掉,避免暫存檔愈 積愈多。 unlink() 在 PHP 中就是刪除檔案的函式。
帶您讀源碼return response()->json([ 'message' => '找到相似圖片', 'similar_images' => $candidates, ]); 回傳
JSON 給前端,內容包含成功訊息與所有相似圖片資料。 } catch (\Exception $e) { 如果整個搜尋流程有任何未處理例外,就會進來這裡。 \Log::error('搜尋圖片錯誤: ' . $e->getMessage()); 把整體搜尋錯誤記錄到 log。 return response()->json(['error' => '搜尋失敗'], 500); 回傳 500 JSON 錯誤訊息,表示伺服器搜尋過程發生問題。 } } 結束 search() 方法。
帶您讀源碼-calculateHammingDistance 方法 /** * 計算兩個十六進制字串的漢明距離(Hamming Distance) */ 這是註解,說明下面的方法用途是計算兩個十六進位字串的漢明距離。 stackoverflow+1 private
function calculateHammingDistance($hex1, $hex2) 宣告一個私有方法,只能在這個 controller 內部使用。 它接收兩個十六進位字串作為參數。 php { if (strlen($hex1) !== strlen($hex2)) { 先檢查兩個字串長度是否相同。 因為漢明距離通常是比較相同長度的資料。
帶您讀源碼php return PHP_INT_MAX; // 長度不同,回傳最 大距離 如果長度不同,就直接回傳很大的整數值,表示它 們差異非常大,不適合拿來比較。 php }
結束長度檢查。 php $distance = 0; 初始化距離變數,先從 0 開始累加。 php $length = strlen($hex1); 取得字串長度,等等迴圈會用到。
帶您讀源碼for ($i = 0; $i < $length; $i++) { 逐字元走訪每一個十六進位字元位置。
$byte1 = hexdec($hex1[$i]); $byte2 = hexdec($hex2[$i]); 把第 i 個十六進位字元轉成十進位數字。 例如 a 會變成 10,f 會變成 15。 $xor = $byte1 ^ $byte2; 對兩個數值做 XOR 位元運算。 如果某些 bit 不同,XOR 後對應 bit 就會是 1,這正好可以拿來 算差異。
帶您讀源碼php while ($xor > 0) { 只要 XOR 結果還大於 0,就表示還有不同的
bit 尚未數 完。 php $distance += $xor & 1; 檢查最低位是否為 1;如果是,就把距離加 1。 這是在累計不同 bit 的數量,也就是漢明距離的核心概 念。 php $xor >>= 1; 把 XOR 結果右移一位,繼續檢查下一個 bit。 } 結束 while,代表這一個十六進位字元的 bit 差異已經算
帶您讀源碼} 結束整個 for 迴圈,代表所有字元都比較完了。 return $distance; 回傳最後算出的總距離。 } } 結束私有方法與整個控制器類別。
整體流程 設計邏輯是:上傳時先把圖片存檔、算出感知 hash、 再把路徑和 hash 存進資料庫;搜尋時則把查詢圖片 也算出 hash,再和資料庫每一筆圖片的 hash 比距離,
距離夠小就視為相似圖片。 其中 DifferenceHash 負責把圖片轉成可比較的感知 特徵,而漢明距離則負責量化兩張圖之間有多像。
設定 API 路由 用POSTMAN測試: localhost:8000/api/upload
設定 API 路由 用POSTMAN測試: localhost:8000/api/upload
資料表
搜圖的 POSTMAN的測 試: localhost:8000/ api/search
結果-
以以以以以以 以以以以以以 TZU FB-29歲女生學程式