Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
以圖搜圖系統開發技術分享
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
滋滋桑
August 04, 2026
21
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
24
使用JavaScript製作互動式網頁導覽列
tzutzu
0
27
Laravel 8 的使用方式
tzutzu
0
32
SPRING BOOT+VUE+資料庫到底是甚麼
tzutzu
0
85
asp.net用北風資料庫來說明實用技術
tzutzu
0
140
資料庫是什麼
tzutzu
0
53
如何準備證照考試
tzutzu
0
140
準備面試
tzutzu
0
390
Featured
See All Featured
Optimizing for Happiness
mojombo
378
71k
Marketing to machines
jonoalderson
1
5.8k
Abbi's Birthday
coloredviolet
4
10k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
58k
[SF Ruby Conf 2025] Rails X
palkan
3
1.4k
Paper Plane
katiecoart
PRO
4
53k
New Earth Scene 8
popppiees
4
2.6k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
450
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
400
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
690
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歲女生學程式