go wails 合图工具
今天把前面 go-walk 做的合图工具用 wails 写下,合并图片的主要逻辑不变,主要是界面上的。
主要的三个功能
1,合成图片自选
2,合成结果预览,自定义缩放查看
3,合成图片导出
创建项目
wails 命令直接创建一个wails vue 的项目
前端展示的界面如下
左侧,打开文件,导出文件的按钮,一个控制缩放的拉条
右侧是展示合成的预览
合成预览的逻辑
1.用户选择图片,然后Go程序拿到选择的文件,进行图片合成,并且计算出每个图片相对左上角的坐标
2.把选择并计算的结果,返回给界面,界面拿到图片链接,图片位置坐标,展示合成的效果
3.可拖动slider 进行缩放,查看效果
4.用户可以点击导出,弹出选择导出的目录,点击确定导出,自动打开导出目录
合成的结果
Go选择文件,计算位置并返回结果
func (a *MergeRes) OpenFileDlg() (position []entity.Plist) {
opts := runtime.OpenDialogOptions{}
filePath, err := runtime.OpenMultipleFilesDialog(a.ctx, opts)
if err != nil {
log.Println(err.Error())
return nil
}
plist := imageMarge.MargeResAny(filePath, "")
for k := range plist {
plist[k].Path = filePath[k]
}
return plist
}
Go导出文件,并打开导出目录
func (a *MergeRes) ExportImg(plistInfo []entity.Plist) {
opts := runtime.OpenDialogOptions{}
dirPath, err := runtime.OpenDirectoryDialog(a.ctx, opts)
if err != nil {
log.Println(err.Error())
return
}
files := make([]string, 0)
for _, v := range plistInfo {
files = append(files, v.Path)
}
randomFileName := time.Now().Format("20060102150405.png")
_ = imageMarge.MargeResAny(files, dirPath+"\\"+randomFileName)
openDir(dirPath)
}
func openDir(dirPath string) {
cmd := exec.Command("cmd.exe", "/c", "start "+dirPath)
err := cmd.Start() //如果用start则直接向后运行
if err != nil {
log.Fatal(err)
}
}
预览合成结果,calcStyle 是动态缩放的样式
<div class="right">
<div class="imgview" :style="calcStyle">
<div v-for="(item, index) in imgList" :key="index" class="img-item-div" :style='{width:item.Width+"px",height:item.Height+"px",top:item.Y+"px",left:item.X+"px"}' >
<Image :src="item.Url" fit="contain" />
</div>
</div>
</div>
// 定义
calcStyle:{
transform:'scale(1)'
},
// 更新
onScaleChange(){
this.calcStyle={
transform:`scale(${this.imgViewScale/100})`
}
},
go完整代码
合成图片的代码参考 juejin.cn/post/726778…
type MergeRes struct {
ctx context.Context
}
func NewMergeRes() *MergeRes {
return &MergeRes{}
}
func (a *MergeRes) SetContext(ctx context.Context) {
a.ctx = ctx
}
func (a *MergeRes) CloseApp() {
// 解绑所有事件
runtime.EventsOffAll(a.ctx)
// 退出系统
os.Exit(0)
}
func (a *MergeRes) OpenFileDlg() (position []entity.Plist) {
opts := runtime.OpenDialogOptions{}
filePath, err := runtime.OpenMultipleFilesDialog(a.ctx, opts)
if err != nil {
log.Println(err.Error())
return nil
}
plist := imageMarge.MargeResAny(filePath, "")
for k := range plist {
plist[k].Path = filePath[k]
}
return plist
}
func (a *MergeRes) GetPosition(files []string) []entity.Plist {
plist := imageMarge.MargeResAny(files, "")
return plist
}
func (a *MergeRes) ExportImg(plistInfo []entity.Plist) {
opts := runtime.OpenDialogOptions{}
dirPath, err := runtime.OpenDirectoryDialog(a.ctx, opts)
if err != nil {
log.Println(err.Error())
return
}
files := make([]string, 0)
for _, v := range plistInfo {
files = append(files, v.Path)
}
randomFileName := time.Now().Format("20060102150405.png")
_ = imageMarge.MargeResAny(files, dirPath+"\\"+randomFileName)
openDir(dirPath)
}
func openDir(dirPath string) {
cmd := exec.Command("cmd.exe", "/c", "start "+dirPath)
err := cmd.Start() //如果用start则直接向后运行
if err != nil {
log.Fatal(err)
}
}
界面文件如下
<template>
<div class="imgMergeApp">
<div class="top">
<div class="tool-bar" style="--wails-draggable: drag">
<div class="title">
<img :src="iconUrl" style="width: 16px; height: 16px" />
{{ name }}
</div>
<div class="tool-btn">
<div style="cursor: pointer" @click="fullScreen">
<Icon type="md-expand" />
</div>
<div style="cursor: pointer" @click="closeApp">
<Icon type="md-power" />
</div>
</div>
</div>
</div>
<div class="bottom" >
<div class="left">
<div>
<Space>
<Button size="small" type="default" @click="openFile" >打开</Button>
<Button size="small" type="default" @click="exportImg" >导出</Button>
</Space>
</div>
<div>
<Input v-model="fileDir" size="small" />
</div>
<div>
<Slider v-model="imgViewScale" @on-input="onScaleChange"></Slider>
</div>
</div>
<div class="right">
<div class="imgview" :style="calcStyle">
<div v-for="(item, index) in imgList" :key="index" class="img-item-div" :style='{width:item.Width+"px",height:item.Height+"px",top:item.Y+"px",left:item.X+"px"}' >
<Image :src="item.Url" fit="contain" />
<!-- <p>{{ item }}</p> -->
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="js">
import { WindowSetSize, WindowToggleMaximise } from "../../wailsjs/runtime/runtime";
import iconUrl from "../assets/images/logo-universal.png";
import { CloseApp, OpenFileDlg,ExportImg} from "../../wailsjs/go/api/MergeRes";
export default {
name:"",
data(){
return {
name: "图片合成Plist",
iconUrl: iconUrl,
winsSize: {
w: 800,
h: 630,
},
fileDir:"",
imgList:[],
calcStyle:{
transform:'scale(1)'
},
imgViewScale:100,
}
},
mounted() {
WindowSetSize(this.winsSize.w, this.winsSize.h);
},
methods:{
fullScreen() {
WindowToggleMaximise();
},
closeApp() {
CloseApp();
},
onScaleChange(){
this.calcStyle={
transform:`scale(${this.imgViewScale/100})`
}
},
openFile() {
this.imgList=[]
OpenFileDlg().then((res) => {
res.forEach((ele) => {
let imgFile = ele.Path
imgFile = imgFile.replace(":", "");
imgFile = "/" + imgFile.split("\\").join("/");
ele.Url = imgFile
this.imgList.push(ele);
});
});
},
exportImg(){
ExportImg(this.imgList)
}
}
}
</script>
<style scoped>
#imgMergeApp {
height: 100%;
width: 100%;
background: none;
}
.top{
height: 30px;
}
.tool-bar {
font-size: 12px;
color: #000;
font-weight: 500;
padding: 0px 9px;
display: flex;
background: #fff;
justify-content: space-between;
align-items: center;
height: 30px;
}
.tool-btn {
display: flex;
}
.tool-btn div {
margin-left: 5px;
font-size: 18px;
}
.title {
display: flex;
justify-content: space-between;
justify-items: center;
}
.bottom{
height: calc( 100vh - 30px );
width: 100%;
display: flex;
}
.bottom .left{
width: 200px;
height: 100%;
padding: 0 10px;
padding-top: 20px;
text-align: left;
border-right: 1px #fff solid;
}
.bottom .left>div{
margin-top: 5px;
}
.right{
flex: 1;
height: 100%;
overflow: auto;
}
.imgview{
position: relative;
transform-origin: left top;
}
.img-item-div{
position: absolute;
}
</style>