266 lines
6.9 KiB
JavaScript
266 lines
6.9 KiB
JavaScript
|
|
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||
|
|
import { ElMessage } from 'element-plus'
|
||
|
|
|
||
|
|
export function useImageTool() {
|
||
|
|
const filePath = ref('')
|
||
|
|
const filePreview = ref('')
|
||
|
|
const imageInfo = ref(null)
|
||
|
|
const processing = ref(false)
|
||
|
|
const resultInfo = ref(null)
|
||
|
|
const outputPath = ref('')
|
||
|
|
const compareImages = ref({ original: '', processed: '' })
|
||
|
|
const config = ref({ defaultOutputDir: '' })
|
||
|
|
|
||
|
|
const showPreview = ref(false)
|
||
|
|
const previewSrc = ref('')
|
||
|
|
const previewIndex = ref(0)
|
||
|
|
const previewScale = ref(1)
|
||
|
|
const previewX = ref(0)
|
||
|
|
const previewY = ref(0)
|
||
|
|
const isDragging = ref(false)
|
||
|
|
const dragStart = ref({ x: 0, y: 0 })
|
||
|
|
|
||
|
|
onMounted(async () => {
|
||
|
|
try {
|
||
|
|
config.value = await window.go.main.FileHandler.GetConfig()
|
||
|
|
} catch (e) {}
|
||
|
|
})
|
||
|
|
|
||
|
|
function formatSize(bytes) {
|
||
|
|
if (!bytes) return '0 B'
|
||
|
|
const k = 1024
|
||
|
|
const sizes = ['B', 'KB', 'MB', 'GB']
|
||
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
||
|
|
}
|
||
|
|
|
||
|
|
function getFileName() {
|
||
|
|
if (!filePath.value) return '未选择文件'
|
||
|
|
return filePath.value.split(/[/\\]/).pop()
|
||
|
|
}
|
||
|
|
|
||
|
|
async function selectFile(fileFilters) {
|
||
|
|
try {
|
||
|
|
const path = await window.go.main.FileHandler.OpenFileDialog('选择文件', fileFilters)
|
||
|
|
if (path) {
|
||
|
|
filePath.value = path
|
||
|
|
resetState()
|
||
|
|
outputPath.value = ''
|
||
|
|
await loadFilePreview()
|
||
|
|
}
|
||
|
|
} catch (e) {
|
||
|
|
ElMessage.error('选择文件失败: ' + e.message)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
async function loadFilePreview() {
|
||
|
|
if (!filePath.value) return
|
||
|
|
try {
|
||
|
|
const b64 = await window.go.main.FileHandler.GetImageBase64(filePath.value)
|
||
|
|
if (b64) {
|
||
|
|
filePreview.value = b64
|
||
|
|
const info = await window.go.main.FileHandler.GetFileInfo(filePath.value)
|
||
|
|
imageInfo.value = info
|
||
|
|
}
|
||
|
|
} catch (e) {
|
||
|
|
console.error('加载预览失败:', e)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function resetState() {
|
||
|
|
resultInfo.value = null
|
||
|
|
compareImages.value = { original: '', processed: '' }
|
||
|
|
previewScale.value = 1
|
||
|
|
previewX.value = 0
|
||
|
|
previewY.value = 0
|
||
|
|
filePreview.value = ''
|
||
|
|
imageInfo.value = null
|
||
|
|
}
|
||
|
|
|
||
|
|
function clearImageFile() {
|
||
|
|
filePath.value = ''
|
||
|
|
filePreview.value = ''
|
||
|
|
imageInfo.value = null
|
||
|
|
resultInfo.value = null
|
||
|
|
compareImages.value = { original: '', processed: '' }
|
||
|
|
outputPath.value = ''
|
||
|
|
}
|
||
|
|
|
||
|
|
async function processFile(req) {
|
||
|
|
if (!filePath.value) {
|
||
|
|
ElMessage.warning('请先选择文件')
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
processing.value = true
|
||
|
|
resultInfo.value = null
|
||
|
|
compareImages.value = { original: '', processed: '' }
|
||
|
|
|
||
|
|
try {
|
||
|
|
const result = await window.go.main.FileHandler.ProcessFile(req)
|
||
|
|
|
||
|
|
if (result.success) {
|
||
|
|
resultInfo.value = {
|
||
|
|
path: result.path,
|
||
|
|
size: formatSize(result.size),
|
||
|
|
sizeBytes: result.size,
|
||
|
|
originalSize: result.originalSize ? formatSize(result.originalSize) : '',
|
||
|
|
originalSizeBytes: result.originalSize || 0,
|
||
|
|
tempPath: result.path,
|
||
|
|
isImageOp: true,
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
const b64 = await window.go.main.FileHandler.GetImageBase64(filePath.value)
|
||
|
|
compareImages.value.original = b64
|
||
|
|
compareImages.value.processed = await window.go.main.FileHandler.GetImageBase64(result.path)
|
||
|
|
if (!compareImages.value.processed) {
|
||
|
|
compareImages.value.processed = b64
|
||
|
|
}
|
||
|
|
} catch (e) {}
|
||
|
|
|
||
|
|
await window.go.main.FileHandler.AddRecentUse({
|
||
|
|
id: req.format,
|
||
|
|
name: '',
|
||
|
|
category: 'image',
|
||
|
|
usedAt: Date.now(),
|
||
|
|
})
|
||
|
|
|
||
|
|
ElMessage.success('处理完成')
|
||
|
|
} else {
|
||
|
|
ElMessage.error(result.message)
|
||
|
|
}
|
||
|
|
} catch (e) {
|
||
|
|
ElMessage.error('处理失败: ' + e.message)
|
||
|
|
} finally {
|
||
|
|
processing.value = false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
async function selectOutputPath(outputFilters, defaultName) {
|
||
|
|
try {
|
||
|
|
const path = await window.go.main.FileHandler.OpenSaveDialog('保存文件', defaultName, outputFilters)
|
||
|
|
if (path) {
|
||
|
|
outputPath.value = path
|
||
|
|
}
|
||
|
|
} catch (e) {}
|
||
|
|
}
|
||
|
|
|
||
|
|
async function downloadResult(outputFilters, getOutputExtFn, getOutputDefaultNameFn) {
|
||
|
|
if (!resultInfo.value?.tempPath) return
|
||
|
|
|
||
|
|
try {
|
||
|
|
const ext = getOutputExtFn ? getOutputExtFn() : '.png'
|
||
|
|
const defaultName = getOutputDefaultNameFn ? getOutputDefaultNameFn() : ('output' + ext)
|
||
|
|
const savePath = await window.go.main.FileHandler.OpenSaveDialog('保存文件', defaultName, outputFilters)
|
||
|
|
|
||
|
|
if (savePath) {
|
||
|
|
const result = await window.go.main.FileHandler.SaveResult(resultInfo.value.tempPath, savePath)
|
||
|
|
if (result.success) {
|
||
|
|
ElMessage.success('文件已保存到: ' + savePath)
|
||
|
|
resultInfo.value.path = savePath
|
||
|
|
} else {
|
||
|
|
ElMessage.error(result.message)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (e) {
|
||
|
|
ElMessage.error('保存失败: ' + e.message)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function openPreview(src, index) {
|
||
|
|
previewSrc.value = src
|
||
|
|
previewIndex.value = index
|
||
|
|
previewScale.value = 1
|
||
|
|
previewX.value = 0
|
||
|
|
previewY.value = 0
|
||
|
|
showPreview.value = true
|
||
|
|
}
|
||
|
|
|
||
|
|
function closePreview() {
|
||
|
|
showPreview.value = false
|
||
|
|
}
|
||
|
|
|
||
|
|
function onWheel(e) {
|
||
|
|
e.preventDefault()
|
||
|
|
const delta = e.deltaY > 0 ? -0.1 : 0.1
|
||
|
|
previewScale.value = Math.max(0.1, Math.min(5, previewScale.value + delta))
|
||
|
|
}
|
||
|
|
|
||
|
|
function onMouseDown(e) {
|
||
|
|
if (e.button !== 0) return
|
||
|
|
isDragging.value = true
|
||
|
|
dragStart.value = { x: e.clientX - previewX.value, y: e.clientY - previewY.value }
|
||
|
|
}
|
||
|
|
|
||
|
|
function onMouseMove(e) {
|
||
|
|
if (!isDragging.value) return
|
||
|
|
previewX.value = e.clientX - dragStart.value.x
|
||
|
|
previewY.value = e.clientY - dragStart.value.y
|
||
|
|
}
|
||
|
|
|
||
|
|
function onMouseUp() {
|
||
|
|
isDragging.value = false
|
||
|
|
}
|
||
|
|
|
||
|
|
function resetPreview() {
|
||
|
|
previewScale.value = 1
|
||
|
|
previewX.value = 0
|
||
|
|
previewY.value = 0
|
||
|
|
}
|
||
|
|
|
||
|
|
function switchPreview(dir) {
|
||
|
|
previewIndex.value = dir
|
||
|
|
previewSrc.value = dir === 0 ? compareImages.value.original : compareImages.value.processed
|
||
|
|
resetPreview()
|
||
|
|
}
|
||
|
|
|
||
|
|
async function openOutputFolder() {
|
||
|
|
if (resultInfo.value?.path) {
|
||
|
|
const dir = resultInfo.value.path.replace(/[/\\][^/\\]+$/, '')
|
||
|
|
try {
|
||
|
|
await window.go.main.FileHandler.OpenFolder(dir)
|
||
|
|
} catch (e) {
|
||
|
|
ElMessage.error('打开文件夹失败')
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
filePath,
|
||
|
|
filePreview,
|
||
|
|
imageInfo,
|
||
|
|
processing,
|
||
|
|
resultInfo,
|
||
|
|
outputPath,
|
||
|
|
compareImages,
|
||
|
|
config,
|
||
|
|
showPreview,
|
||
|
|
previewSrc,
|
||
|
|
previewIndex,
|
||
|
|
previewScale,
|
||
|
|
previewX,
|
||
|
|
previewY,
|
||
|
|
isDragging,
|
||
|
|
dragStart,
|
||
|
|
formatSize,
|
||
|
|
getFileName,
|
||
|
|
selectFile,
|
||
|
|
loadFilePreview,
|
||
|
|
resetState,
|
||
|
|
clearImageFile,
|
||
|
|
processFile,
|
||
|
|
selectOutputPath,
|
||
|
|
downloadResult,
|
||
|
|
openPreview,
|
||
|
|
closePreview,
|
||
|
|
onWheel,
|
||
|
|
onMouseDown,
|
||
|
|
onMouseMove,
|
||
|
|
onMouseUp,
|
||
|
|
resetPreview,
|
||
|
|
switchPreview,
|
||
|
|
openOutputFolder,
|
||
|
|
}
|
||
|
|
}
|