Vue-Cropper:全面掌握圖片裁剪組件

Vue-Cropper 完全學習指南:Vue圖片裁剪組件

🎯 什么是 Vue-Cropper?

Vue-Cropper 是一個簡單易用的Vue圖片裁剪組件,支持Vue2和Vue3。它提供了豐富的配置選項和回調方法,可以滿足各種圖片裁剪需求。

🌟 核心特點

  • 簡單易用:API設計簡潔,快速上手
  • 功能豐富:支持縮放、旋轉、移動等操作
  • 高度可配置:提供30+個配置選項
  • 實時預覽:支持實時預覽裁剪效果
  • 多種輸出格式:支持jpeg、png、webp格式
  • 響應式設計:適配移動端和桌面端
  • Vue2/Vue3兼容:同時支持Vue 2.x和Vue 3.x

📦 安裝與引入

NPM 安裝

# Vue 2.x 版本
npm install vue-cropper# Vue 3.x 版本
npm install vue-cropper@next

引入方式

全局引入
// Vue 2.x
import Vue from 'vue'
import VueCropper from 'vue-cropper' 
import 'vue-cropper/dist/index.css'Vue.use(VueCropper)// Vue 3.x
import { createApp } from 'vue'
import VueCropper from 'vue-cropper'
import 'vue-cropper/dist/index.css'const app = createApp({})
app.use(VueCropper)
局部引入
// Vue 2.x
import { VueCropper } from 'vue-cropper'
import 'vue-cropper/dist/index.css'export default {components: {VueCropper}
}// Vue 3.x
import VueCropper from 'vue-cropper'
import 'vue-cropper/dist/index.css'export default {components: {VueCropper}
}

🚀 基礎使用

1. 基本示例

<template><div class="cropper-container"><!-- 圖片裁剪組件 --><vue-cropperref="cropper":img="option.img":outputSize="option.outputSize":outputType="option.outputType":info="option.info":canScale="option.canScale":autoCrop="option.autoCrop":autoCropWidth="option.autoCropWidth":autoCropHeight="option.autoCropHeight":fixed="option.fixed":fixedNumber="option.fixedNumber"@realTime="realTime"@imgLoad="imgLoad"style="width: 100%; height: 400px;"></vue-cropper><!-- 控制按鈕 --><div class="btn-group"><button @click="startCrop">開始裁剪</button><button @click="stopCrop">停止裁剪</button><button @click="clearCrop">清除裁剪</button><button @click="changeScale(1)">放大</button><button @click="changeScale(-1)">縮小</button><button @click="rotateLeft">左旋轉</button><button @click="rotateRight">右旋轉</button><button @click="getCropData">獲取裁剪結果</button></div><!-- 實時預覽 --><div class="preview-box"><div class="preview" :style="previews.div"><img :src="previews.url" :style="previews.img"></div></div></div>
</template><script>
import VueCropper from 'vue-cropper'export default {name: 'CropperDemo',components: {VueCropper},data() {return {option: {img: '/path/to/your/image.jpg',  // 裁剪圖片的地址outputSize: 1,         // 裁剪生成圖片的質量(0.1-1)outputType: 'jpeg',    // 裁剪生成圖片的格式info: true,           // 顯示裁剪框的大小信息canScale: true,       // 圖片是否允許滾輪縮放autoCrop: true,       // 是否默認生成截圖框autoCropWidth: 300,   // 默認生成截圖框寬度autoCropHeight: 200,  // 默認生成截圖框高度fixed: true,          // 是否開啟截圖框寬高固定比例fixedNumber: [3, 2],  // 截圖框的寬高比例},previews: {}}},methods: {// 實時預覽realTime(data) {this.previews = data},// 圖片加載完成imgLoad(msg) {console.log('圖片加載:', msg)},// 開始裁剪startCrop() {this.$refs.cropper.startCrop()},// 停止裁剪stopCrop() {this.$refs.cropper.stopCrop()},// 清除裁剪clearCrop() {this.$refs.cropper.clearCrop()},// 縮放changeScale(num) {this.$refs.cropper.changeScale(num)},// 左旋轉rotateLeft() {this.$refs.cropper.rotateLeft()},// 右旋轉rotateRight() {this.$refs.cropper.rotateRight()},// 獲取裁剪結果getCropData() {// 獲取base64數據this.$refs.cropper.getCropData((data) => {console.log('Base64結果:', data)})// 獲取blob數據this.$refs.cropper.getCropBlob((data) => {console.log('Blob結果:', data)})}}
}
</script><style scoped>
.cropper-container {max-width: 800px;margin: 0 auto;
}.btn-group {margin: 20px 0;text-align: center;
}.btn-group button {margin: 0 5px;padding: 8px 16px;background: #007bff;color: white;border: none;border-radius: 4px;cursor: pointer;
}.btn-group button:hover {background: #0056b3;
}.preview-box {margin-top: 20px;
}.preview {width: 200px;height: 133px;overflow: hidden;border: 1px solid #ccc;margin: 0 auto;
}
</style>

?? 配置選項詳解

基礎配置

參數說明類型默認值可選值
img裁剪圖片的地址Stringurl地址、base64、blob
outputSize裁剪生成圖片的質量Number10.1 ~ 1
outputType裁剪生成圖片的格式Stringjpgjpeg、png、webp
info圖片的信息展示Booleantruetrue、false
canScale圖片是否允許滾輪縮放Booleantruetrue、false

裁剪框配置

參數說明類型默認值可選值
autoCrop是否默認生成截圖框Booleanfalsetrue、false
autoCropWidth默認生成截圖框寬度Number容器的80%0 ~ max
autoCropHeight默認生成截圖框高度Number容器的80%0 ~ max
fixed是否開啟截圖框寬高固定比例Booleanfalsetrue、false
fixedNumber截圖框的寬高比例Array[1, 1][寬度, 高度]
fixedBox固定截圖框大小不允許改變Booleanfalsetrue、false
centerBox截圖框是否被限制在圖片里面Booleanfalsetrue、false

交互配置

參數說明類型默認值可選值
canMove上傳圖片是否可以移動Booleantruetrue、false
canMoveBox截圖框能否拖動Booleantruetrue、false
original上傳圖片按照原始比例渲染Booleanfalsetrue、false
full是否輸出原圖比例的截圖Booleanfalsetrue、false
high是否按照設備的dpr輸出等比例圖片Booleantruetrue、false

高級配置

參數說明類型默認值可選值
infoTruetrue為展示真實輸出圖片寬高,false展示看到的截圖框寬高Booleanfalsetrue、false
maxImgSize限制圖片最大寬度和高度Number20000 ~ max
enlarge圖片根據截圖框輸出比例倍數Number10 ~ max
mode圖片默認渲染方式Stringcontaincontain、cover、100px、100% auto
limitMinSize裁剪框限制最小區域Number/Array/String10Number、Array、String
fillColor導出時背景顏色填充String#ffffff、white

🔄 回調方法

@realTime 實時預覽事件

methods: {realTime(data) {console.log('實時預覽數據:', data)/*data 包含以下屬性:{img: '...',     // 裁剪的圖片base64w: 200,         // 裁剪框寬度h: 100,         // 裁剪框高度div: {...},     // 預覽容器樣式url: '...'      // 圖片地址}*/// 設置預覽樣式this.previews = data// 自定義預覽大小this.previewStyle1 = {width: data.w + 'px',height: data.h + 'px',overflow: 'hidden',margin: '0',zoom: 0.5  // 縮放比例}}
}

@imgMoving 圖片移動回調

methods: {imgMoving(data) {console.log('圖片移動:', data)/*data 包含:{moving: true,  // 是否在移動axis: {x1: 100,     // 左上角x坐標x2: 300,     // 右下角x坐標y1: 50,      // 左上角y坐標y2: 200      // 右下角y坐標}}*/}
}

@cropMoving 截圖框移動回調

methods: {cropMoving(data) {console.log('截圖框移動:', data)// 數據結構與imgMoving相同}
}

@imgLoad 圖片加載回調

methods: {imgLoad(msg) {if (msg === 'success') {console.log('圖片加載成功')} else {console.log('圖片加載失敗')}}
}

🛠? 內置方法

裁剪控制方法

// 開始裁剪
this.$refs.cropper.startCrop()// 停止裁剪
this.$refs.cropper.stopCrop()// 清除裁剪框
this.$refs.cropper.clearCrop()// 自動生成截圖框
this.$refs.cropper.goAutoCrop()

圖片操作方法

// 縮放圖片 (正數放大,負數縮小)
this.$refs.cropper.changeScale(1)   // 放大
this.$refs.cropper.changeScale(-1)  // 縮小// 旋轉圖片
this.$refs.cropper.rotateLeft()   // 左旋轉90度
this.$refs.cropper.rotateRight()  // 右旋轉90度

獲取坐標信息

// 獲取圖片基于容器的坐標點
const imgAxis = this.$refs.cropper.getImgAxis()// 獲取截圖框基于容器的坐標點
const cropAxis = this.$refs.cropper.getCropAxis()// 獲取截圖框寬高
const cropW = this.$refs.cropper.cropW
const cropH = this.$refs.cropper.cropH

獲取裁剪結果

// 獲取base64格式
this.$refs.cropper.getCropData((data) => {console.log('Base64數據:', data)// 可以直接用于img標簽的srcthis.resultImg = data
})// 獲取blob格式
this.$refs.cropper.getCropBlob((data) => {console.log('Blob數據:', data)// 可以用于FormData上傳const formData = new FormData()formData.append('file', data, 'cropped.jpg')
})

🎨 實際應用案例

案例1:頭像上傳裁剪

<template><div class="avatar-upload"><!-- 文件選擇 --><input type="file" ref="fileInput"@change="handleFileChange"accept="image/*"style="display: none"><!-- 當前頭像展示 --><div class="current-avatar" @click="selectFile"><img v-if="avatarUrl" :src="avatarUrl" alt="頭像"><div v-else class="avatar-placeholder">點擊上傳頭像</div></div><!-- 裁剪彈窗 --><div v-if="showCropper" class="cropper-modal"><div class="cropper-content"><h3>裁剪頭像</h3><vue-cropperref="cropper":img="tempImage":outputSize="1":outputType="'jpeg'":autoCrop="true":autoCropWidth="200":autoCropHeight="200":fixed="true":fixedNumber="[1, 1]":centerBox="true"style="width: 100%; height: 400px;"></vue-cropper><div class="cropper-buttons"><button @click="cancelCrop">取消</button><button @click="confirmCrop">確認</button></div></div></div></div>
</template><script>
export default {data() {return {avatarUrl: '',tempImage: '',showCropper: false}},methods: {selectFile() {this.$refs.fileInput.click()},handleFileChange(e) {const file = e.target.files[0]if (!file) return// 驗證文件類型if (!file.type.startsWith('image/')) {alert('請選擇圖片文件')return}// 驗證文件大小 (5MB)if (file.size > 5 * 1024 * 1024) {alert('圖片大小不能超過5MB')return}// 讀取文件并顯示裁剪器const reader = new FileReader()reader.onload = (e) => {this.tempImage = e.target.resultthis.showCropper = true}reader.readAsDataURL(file)},cancelCrop() {this.showCropper = falsethis.tempImage = ''this.$refs.fileInput.value = ''},confirmCrop() {this.$refs.cropper.getCropBlob((blob) => {// 上傳到服務器this.uploadAvatar(blob)})},async uploadAvatar(blob) {const formData = new FormData()formData.append('avatar', blob, 'avatar.jpg')try {const response = await fetch('/api/upload-avatar', {method: 'POST',body: formData})const result = await response.json()if (result.success) {this.avatarUrl = result.urlthis.showCropper = falsethis.tempImage = ''alert('頭像上傳成功')}} catch (error) {console.error('上傳失敗:', error)alert('上傳失敗,請重試')}}}
}
</script><style scoped>
.current-avatar {width: 100px;height: 100px;border-radius: 50%;overflow: hidden;cursor: pointer;border: 2px solid #ddd;display: flex;align-items: center;justify-content: center;
}.current-avatar img {width: 100%;height: 100%;object-fit: cover;
}.avatar-placeholder {color: #999;font-size: 12px;text-align: center;
}.cropper-modal {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background: rgba(0, 0, 0, 0.8);display: flex;align-items: center;justify-content: center;z-index: 1000;
}.cropper-content {background: white;padding: 20px;border-radius: 8px;width: 90%;max-width: 600px;
}.cropper-buttons {margin-top: 20px;text-align: center;
}.cropper-buttons button {margin: 0 10px;padding: 8px 20px;border: none;border-radius: 4px;cursor: pointer;
}
</style>

案例2:商品圖片批量裁剪

<template><div class="batch-cropper"><h2>商品圖片批量裁剪</h2><!-- 上傳區域 --><div class="upload-area" @drop="handleDrop" @dragover.prevent><input type="file" ref="fileInput"@change="handleFileSelect"multipleaccept="image/*"style="display: none"><button @click="selectFiles">選擇圖片</button><p>或拖拽圖片到此區域</p></div><!-- 圖片列表 --><div class="image-list"><div v-for="(item, index) in imageList" :key="index"class="image-item":class="{ active: currentIndex === index }"@click="selectImage(index)"><img :src="item.preview" alt=""><div class="image-status"><span v-if="item.cropped" class="status-success">?</span><span v-else class="status-pending">○</span></div></div></div><!-- 裁剪區域 --><div v-if="currentImage" class="cropper-area"><vue-cropperref="cropper":img="currentImage.src":outputSize="0.8":outputType="'jpeg'":autoCrop="true":autoCropWidth="300":autoCropHeight="300":fixed="true":fixedNumber="[1, 1]"style="width: 100%; height: 400px;"></vue-cropper><div class="cropper-controls"><button @click="prevImage" :disabled="currentIndex === 0">上一張</button><button @click="cropCurrent">裁剪當前圖片</button><button @click="nextImage" :disabled="currentIndex === imageList.length - 1">下一張</button><button @click="batchCrop" class="batch-btn">批量裁剪</button></div></div><!-- 結果展示 --><div v-if="croppedImages.length" class="results"><h3>裁剪結果</h3><div class="result-grid"><div v-for="(result, index) in croppedImages" :key="index" class="result-item"><img :src="result.url" alt=""><button @click="downloadImage(result, index)">下載</button></div></div></div></div>
</template><script>
export default {data() {return {imageList: [],currentIndex: 0,croppedImages: []}},computed: {currentImage() {return this.imageList[this.currentIndex] || null}},methods: {selectFiles() {this.$refs.fileInput.click()},handleFileSelect(e) {this.processFiles(e.target.files)},handleDrop(e) {e.preventDefault()this.processFiles(e.dataTransfer.files)},processFiles(files) {Array.from(files).forEach(file => {if (file.type.startsWith('image/')) {const reader = new FileReader()reader.onload = (e) => {this.imageList.push({file,src: e.target.result,preview: e.target.result,cropped: false})}reader.readAsDataURL(file)}})},selectImage(index) {this.currentIndex = index},prevImage() {if (this.currentIndex > 0) {this.currentIndex--}},nextImage() {if (this.currentIndex < this.imageList.length - 1) {this.currentIndex++}},cropCurrent() {this.$refs.cropper.getCropData((data) => {this.croppedImages.push({url: data,originalIndex: this.currentIndex})this.imageList[this.currentIndex].cropped = true// 自動切換到下一張if (this.currentIndex < this.imageList.length - 1) {this.nextImage()}})},batchCrop() {const uncroppedImages = this.imageList.filter(item => !item.cropped)if (uncroppedImages.length === 0) {alert('所有圖片都已裁剪完成')return}if (confirm(`還有${uncroppedImages.length}張圖片未裁剪,是否使用當前設置批量裁剪?`)) {this.processBatchCrop()}},processBatchCrop() {// 這里可以實現批量裁剪邏輯// 由于vue-cropper需要逐個處理,這里示例批量應用相同設置alert('批量裁剪功能開發中...')},downloadImage(result, index) {const link = document.createElement('a')link.href = result.urllink.download = `cropped-image-${index + 1}.jpg`link.click()}}
}
</script><style scoped>
.upload-area {border: 2px dashed #ccc;padding: 40px;text-align: center;margin-bottom: 20px;border-radius: 8px;
}.upload-area:hover {border-color: #007bff;
}.image-list {display: flex;gap: 10px;margin-bottom: 20px;overflow-x: auto;
}.image-item {position: relative;width: 80px;height: 80px;cursor: pointer;border: 2px solid transparent;border-radius: 4px;
}.image-item.active {border-color: #007bff;
}.image-item img {width: 100%;height: 100%;object-fit: cover;border-radius: 4px;
}.image-status {position: absolute;top: -5px;right: -5px;width: 20px;height: 20px;border-radius: 50%;background: white;display: flex;align-items: center;justify-content: center;border: 1px solid #ccc;
}.status-success {color: green;
}.cropper-controls {margin-top: 20px;text-align: center;
}.cropper-controls button {margin: 0 5px;padding: 8px 16px;border: none;border-radius: 4px;cursor: pointer;
}.batch-btn {background: #28a745 !important;color: white;
}.results {margin-top: 40px;
}.result-grid {display: grid;grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));gap: 20px;
}.result-item {text-align: center;
}.result-item img {width: 100%;border-radius: 4px;border: 1px solid #ddd;
}
</style>

🔧 最佳實踐

1. 性能優化

// 大圖片預處理
methods: {async processLargeImage(file) {// 壓縮圖片尺寸const canvas = document.createElement('canvas')const ctx = canvas.getContext('2d')const img = new Image()return new Promise((resolve) => {img.onload = () => {const maxSize = 1920let { width, height } = imgif (width > maxSize || height > maxSize) {if (width > height) {height = (height * maxSize) / widthwidth = maxSize} else {width = (width * maxSize) / heightheight = maxSize}}canvas.width = widthcanvas.height = heightctx.drawImage(img, 0, 0, width, height)resolve(canvas.toDataURL('image/jpeg', 0.8))}img.src = URL.createObjectURL(file)})}
}

2. 移動端適配

/* 移動端樣式 */
@media (max-width: 768px) {.vue-cropper {height: 300px !important;}.cropper-controls {display: flex;flex-direction: column;gap: 10px;}.cropper-controls button {width: 100%;padding: 12px;}
}

3. 錯誤處理

methods: {handleError(error) {console.error('裁剪錯誤:', error)// 用戶友好的錯誤提示const errorMessages = {'file-too-large': '文件太大,請選擇小于5MB的圖片','invalid-format': '不支持的圖片格式','crop-failed': '裁剪失敗,請重試'}this.showMessage(errorMessages[error.type] || '操作失敗,請重試')},showMessage(message) {// 實現消息提示alert(message)}
}

🎯 總結

Vue-Cropper 是一個功能強大的Vue圖片裁剪組件,它提供了:

? 豐富的配置選項:滿足各種裁剪需求
? 完整的API接口:支持所有常用操作
? 實時預覽功能:提供良好的用戶體驗
? 多種輸出格式:支持不同的應用場景
? Vue2/Vue3兼容:適配不同版本的Vue項目
? 移動端友好:支持觸摸操作和響應式設計

通過合理使用Vue-Cropper,您可以輕松實現頭像上傳、商品圖片處理、證件照裁剪等功能,為用戶提供專業的圖片處理體驗。


開始您的圖片裁剪之旅吧! 📸

💡 開發建議:在實際項目中,建議結合文件上傳、圖片壓縮、格式轉換等功能,構建完整的圖片處理流程。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/82437.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/82437.shtml
英文地址,請注明出處:http://en.pswp.cn/web/82437.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[Go] Option選項設計模式 — — 編程方式基礎入門

[Go] Option選項設計模式 — — 編程方式基礎入門 全部代碼地址&#xff0c;歡迎?? Github&#xff1a;https://github.com/ziyifast/ziyifast-code_instruction/tree/main/go-demo/go-option 1 介紹 在 Go 開發中&#xff0c;我們經常遇到需要處理多參數配置的場景。傳統方…

【Unity開發】控制手機移動端的震動

&#x1f43e; 個人主頁 &#x1f43e; 阿松愛睡覺&#xff0c;橫豎醒不來 &#x1f3c5;你可以不屠龍&#xff0c;但不能不磨劍&#x1f5e1; 目錄 一、前言二、Unity的Handheld.Vibrate()三、調用Android原生代碼四、NiceVibrations插件五、DeviceVibration插件六、控制游戲手…

Linux 軟件安裝方式全解(適用于 CentOS/RHEL 系統)

&#x1f427; Linux 軟件安裝方式全解&#xff08;適用于 CentOS/RHEL 系統&#xff09; 在 Linux 系統中&#xff0c;軟件安裝方式豐富多樣&#xff0c;常見于以下幾種方式&#xff1a; 安裝方式命令/工具說明軟件包管理器&#xff08;推薦&#xff09;yum, dnf, apt, zypp…

前端面試題-HTML篇

1. 請談談你對 Web 標準以及 W3C 的理解和認識。 我對 Web 標準 的理解是,它就像是互聯網世界的“交通規則”,由 W3C(World Wide Web Consortium,萬維網聯盟) 這樣一個國際性組織制定。這些規則規范了我們在編寫 HTML、CSS 和 JavaScript 時應該遵循的語法和行為,比如要…

ERROR: column cl.udt_name does not exist LINE 1 navicat打開金倉表報錯

描述&#xff1a; ERROR: column cl.udt_name does not exist LINE 1: …a.columns cl LEFT JOlN pg type ty ON ty.typname cl.udt nam. navicat連上金倉數據庫之后&#xff0c;想打開一張表看看&#xff0c;每張表都報這個錯&#xff0c;打不開 解決方案&#xff1a; 網上…

2025年- H61-Lc169--74.搜索二維矩陣(二分查找)--Java版

1.題目描述 2.思路 方法一&#xff1a; 定義其實坐標&#xff0c;右上角的元素&#xff08;0&#xff0c;n-1&#xff09;。進入while循環&#xff08;注意邊界條件&#xff0c;行數小于m&#xff0c;列數要&#xff1e;0&#xff09;從右上角開始開始向左遍歷&#xff08;比當…

Jupyter MCP服務器部署實戰:AI模型與Python環境無縫集成教程

Jupyter MCP 服務器是基于模型上下文協議&#xff08;Model Context Protocol, MCP&#xff09;的 Jupyter 環境擴展組件&#xff0c;它能夠實現大型語言模型與實時編碼會話的無縫集成。該服務器通過標準化的協議接口&#xff0c;使 AI 模型能夠安全地訪問和操作 Jupyter 的核心…

MySQL下載安裝配置環境變量

MySQL下載安裝配置環境變量 文章目錄 MySQL下載安裝配置環境變量一、安裝MySQL1.1 下載1.2 安裝 二、查看MySQL服務是否啟動三、配置環境變量四、驗證 一、安裝MySQL 1.1 下載 官網社區版&#xff08;免費版&#xff09;&#xff1a;https://dev.mysql.com/downloads/mysql/ …

WSL 安裝 Debian 12 后,Linux 如何安裝 curl , quickjs ?

在 WSL 的 Debian 12 系統中安裝 curl 非常簡單&#xff0c;你可以直接使用 APT 包管理器從官方倉庫安裝。以下是詳細步驟&#xff1a; 1. 更新軟件包索引 首先確保系統的包索引是最新的&#xff1a; sudo apt update2. 安裝 curl 執行以下命令安裝 curl&#xff1a; sudo…

Linux入門(十四)rpmyum

RPM 是RedHat PackManager的縮寫 rpm是用于互聯網下載包的打包及安裝工具 rpm查詢 查詢已安裝的rpm列表 rpm -qa查看系統是否安裝了psmisc rpm -qa | grep psmisc rpm -q psmisc查詢軟件包信息 rpm -qi psmisc查詢軟件包中的文件 rpm -ql psmisc根據文件全路徑 查詢文件所…

[git]忽略.gitignore文件

git rm --cached .gitignore 是一個 Git 命令,主要用于 從版本控制中移除已追蹤的 .gitignore 文件,但保留該文件在本地工作目錄中。以下是詳細解析: 一、命令拆解與核心作用 語法解析 git rm:Git 的刪除命令,用于從版本庫(Repository)中移除文件。--cached:關鍵參數…

Hive SQL 中 BY 系列關鍵字全解析:從排序、分發到分組的核心用法

一、排序與分發相關 BY 關鍵字 1. ORDER BY&#xff1a;全局統一排序 作用&#xff1a;對查詢結果進行全局排序&#xff0c;確保最終結果集完全有序&#xff08;僅允許單個 Reducer 處理數據&#xff09;。 語法&#xff1a; SELECT * FROM table_name ORDER BY column1 [A…

網絡爬蟲 - App爬蟲及代理的使用(十一)

App爬蟲及代理的使用 一、App抓包1. App爬蟲原理2. reqable的安裝與配置1. reqable安裝教程2. reqable的配置3. 模擬器的安裝與配置1. 夜神模擬器的安裝2. 夜神模擬器的配置4. 內聯調試及注意事項1. 軟件啟動順序2. 開啟抓包功能3. reqable面板功能4. 夜神模擬器設置項5. 注意事…

【25.06】FISCOBCOS使用caliper自定義測試 通過webase 單機四節點 helloworld等進行測試

前置條件 安裝一個Ubuntu20+的鏡像 基礎環境安裝 Git cURL vim jq sudo apt install -y git curl vim jq Docker和Docker-compose 這個命令會自動安裝docker sudo apt install docker-compose sudo chmod +x /usr/bin/docker-compose docker versiondocker-compose vers…

【基礎】Unity中Camera組件知識點

一、投影模式 (Projection) 1. 透視模式 (Perspective) 原理&#xff1a;模擬人眼&#xff0c;近大遠小&#xff08;錐形體視錐&#xff09; 核心參數&#xff1a; Field of View (FOV)&#xff1a;垂直視場角 典型值&#xff1a;第一人稱 60-90&#xff0c;駕駛艙 30-45 特…

PCA(K-L變換)人臉識別(python實現)

數據集分析 ORL數據集&#xff0c; 總共40個人&#xff0c;每個人拍攝10張人臉照片 照片格式為灰度圖像&#xff0c;尺寸112 * 92 特點&#xff1a; 圖像質量高&#xff0c;無需灰度運算、去噪等預處理 人臉已經位于圖像正中央&#xff0c;但部分圖像角度傾斜&#xff08;可…

【Git】View Submitted Updates——diff、show、log

在 Git 中查看更新的內容&#xff08;即工作區、暫存區或提交之間的差異&#xff09;是日常開發中的常見操作。以下是常用的命令和場景說明&#xff1a; 文章目錄 1、查看工作區與暫存區的差異2、查看提交歷史中的差異3、查看工作區與最新提交的差異4、查看兩個提交之間的差異5…

deepseek原理和項目實戰筆記2 -- deepseek核心架構

混合專家&#xff08;MoE&#xff09; ??混合專家&#xff08;Mixture of Experts, MoE&#xff09;?? 是一種機器學習模型架構&#xff0c;其核心思想是通過組合多個“專家”子模型&#xff08;通常為小型神經網絡&#xff09;來處理不同輸入&#xff0c;從而提高模型的容…

GPU層次結構(Nvidia和Apple M芯片,從硬件到pytorch)

這里寫目錄標題 0、驅動pytorch環境安裝驗證1.window環境2.Mac Apple M芯片環境 1、Nvidia顯卡驅動、CUDA、cuDNN關系匯總1**1. Nvidia顯卡驅動&#xff08;Graphics Driver&#xff09;****2. CUDA&#xff08;Compute Unified Device Architecture&#xff09;****3. cuDNN&a…

OpenWrt 搭建 samba 服務器的方法并解決 Windows 不允許訪問匿名服務器(0x80004005的錯誤)的方法

文章目錄 一、安裝所需要的軟件二、配置自動掛載三、配置 Samba 服務器四、配置 Samba 訪問用戶和密碼&#xff08;可選&#xff09;新建 Samba 專門的用戶添加無密碼的 Samba 賬戶使用root賬戶 五、解決 Windows 無法匿名訪問Samba方案一 配置無密碼的Samba賬戶并啟用匿名訪問…