export image functionality
This commit is contained in:
@@ -5,6 +5,7 @@ go 1.25.6
|
||||
require (
|
||||
fyne.io/fyne/v2 v2.7.2
|
||||
github.com/aquilax/go-perlin v1.1.0
|
||||
github.com/chai2010/webp v1.4.0
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/ojrac/opensimplex-go v1.0.2
|
||||
)
|
||||
@@ -37,9 +38,9 @@ require (
|
||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
|
||||
github.com/stretchr/testify v1.11.1 // indirect
|
||||
github.com/yuin/goldmark v1.7.8 // indirect
|
||||
golang.org/x/image v0.24.0 // indirect
|
||||
golang.org/x/image v0.35.0 // indirect
|
||||
golang.org/x/net v0.35.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
golang.org/x/text v0.33.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -6,6 +6,8 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/aquilax/go-perlin v1.1.0 h1:Gg+3jQ24wT4Y5GI7TCRLmYarzUG0k+n/JATFqOimb7s=
|
||||
github.com/aquilax/go-perlin v1.1.0/go.mod h1:z9Rl7EM4BZY0Ikp2fEN1I5mKSOJ26HQpk0O2TBdN2HE=
|
||||
github.com/chai2010/webp v1.4.0 h1:6DA2pkkRUPnbOHvvsmGI3He1hBKf/bkRlniAiSGuEko=
|
||||
github.com/chai2010/webp v1.4.0/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -72,15 +74,15 @@ github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD
|
||||
github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
|
||||
github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=
|
||||
golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8=
|
||||
golang.org/x/image v0.35.0 h1:LKjiHdgMtO8z7Fh18nGY6KDcoEtVfsgLDPeLyguqb7I=
|
||||
golang.org/x/image v0.35.0/go.mod h1:MwPLTVgvxSASsxdLzKrl8BRFuyqMyGhLwmC+TO1Sybk=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -12,15 +12,21 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"image/jpeg"
|
||||
"strings"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/app"
|
||||
"fyne.io/fyne/v2/canvas"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/dialog"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
|
||||
"github.com/chai2010/webp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
a := app.New()
|
||||
a := app.NewWithID("com.example.rpgcitymaker")
|
||||
a.Settings().SetTheme(&CustomTheme{a.Settings().Theme()})
|
||||
w := a.NewWindow("RPG City Maker")
|
||||
w.Resize(fyne.NewSize(800, 600))
|
||||
@@ -254,6 +260,9 @@ func main() {
|
||||
|
||||
var generateBtn *widget.Button
|
||||
progressBar := NewTextOverlayProgressBar()
|
||||
exportBtn := widget.NewButton("Export", func() {
|
||||
showSaveDialog(w, canvasImg.Image, settings)
|
||||
})
|
||||
|
||||
generateBtn = widget.NewButton("Generate", func() {
|
||||
go func() {
|
||||
@@ -437,6 +446,8 @@ func main() {
|
||||
generateBtn,
|
||||
errorLabel,
|
||||
progressBar,
|
||||
widget.NewSeparator(),
|
||||
exportBtn,
|
||||
))
|
||||
|
||||
tabs := container.NewAppTabs(
|
||||
@@ -464,3 +475,86 @@ func main() {
|
||||
w.SetContent(split)
|
||||
w.ShowAndRun()
|
||||
}
|
||||
|
||||
func showSaveDialog(win fyne.Window, img image.Image, settings *Settings) {
|
||||
fileNameEntry := widget.NewEntry()
|
||||
fileNameEntry.SetPlaceHolder("image")
|
||||
|
||||
formatSelect := widget.NewSelect([]string{"PNG", "JPG", "WEBP"}, nil)
|
||||
formatSelect.SetSelected("PNG")
|
||||
|
||||
pathLabel := widget.NewLabel(settings.LastExportPath)
|
||||
|
||||
browseBtn := widget.NewButton("Browse", func() {
|
||||
dialog.ShowFolderOpen(func(uri fyne.ListableURI, err error) {
|
||||
if err != nil {
|
||||
log.Println("Error opening folder dialog:", err)
|
||||
return
|
||||
}
|
||||
if uri == nil {
|
||||
return
|
||||
}
|
||||
settings.LastExportPath = uri.Path()
|
||||
pathLabel.SetText(settings.LastExportPath)
|
||||
}, win)
|
||||
})
|
||||
|
||||
content := container.NewVBox(
|
||||
widget.NewLabel("Save to:"),
|
||||
container.NewBorder(nil, nil, nil, browseBtn, pathLabel),
|
||||
widget.NewLabel("Filename:"),
|
||||
fileNameEntry,
|
||||
widget.NewLabel("Format:"),
|
||||
formatSelect,
|
||||
)
|
||||
|
||||
saveDialog := dialog.NewCustom("Export Image", "Cancel", content, win)
|
||||
|
||||
saveBtn := widget.NewButton("Save", func() {
|
||||
fileName := fileNameEntry.Text
|
||||
if fileName == "" {
|
||||
return
|
||||
}
|
||||
|
||||
filePath := filepath.Join(pathLabel.Text, fileName+"."+strings.ToLower(formatSelect.Selected))
|
||||
settings.LastExportPath = filepath.Dir(filePath)
|
||||
|
||||
file, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
log.Println("Error creating file:", err)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
switch formatSelect.Selected {
|
||||
case "PNG":
|
||||
err = png.Encode(file, img)
|
||||
case "JPG":
|
||||
err = jpeg.Encode(file, img, nil)
|
||||
case "WEBP":
|
||||
err = webp.Encode(file, img, &webp.Options{Lossless: true})
|
||||
}
|
||||
if err != nil {
|
||||
log.Println("Failed to encode image:", err)
|
||||
}
|
||||
saveDialog.Hide()
|
||||
})
|
||||
saveBtn.Disable()
|
||||
|
||||
fileNameEntry.OnChanged = func(text string) {
|
||||
if text == "" {
|
||||
saveBtn.Disable()
|
||||
} else {
|
||||
saveBtn.Enable()
|
||||
}
|
||||
}
|
||||
|
||||
saveDialog.SetButtons([]fyne.CanvasObject{
|
||||
widget.NewButton("Cancel", func() {
|
||||
saveDialog.Hide()
|
||||
}),
|
||||
saveBtn,
|
||||
})
|
||||
|
||||
saveDialog.Show()
|
||||
}
|
||||
|
||||
+15
@@ -24,6 +24,7 @@ type Settings struct {
|
||||
MinRiverWidth float64 `json:"min_river_width"`
|
||||
MaxRiverWidth float64 `json:"max_river_width"`
|
||||
RiverCurvyness float64 `json:"river_curvyness"`
|
||||
LastExportPath string `json:"last_export_path"`
|
||||
}
|
||||
|
||||
func (s *Settings) Save() error {
|
||||
@@ -58,6 +59,10 @@ func LoadSettings() (*Settings, error) {
|
||||
file, err := os.Open(configFile)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
homeDir = "."
|
||||
}
|
||||
return &Settings{
|
||||
Detail: 1,
|
||||
Roughness: 0,
|
||||
@@ -75,6 +80,7 @@ func LoadSettings() (*Settings, error) {
|
||||
MinRiverWidth: 1,
|
||||
MaxRiverWidth: 5,
|
||||
RiverCurvyness: 50,
|
||||
LastExportPath: homeDir,
|
||||
}, nil
|
||||
}
|
||||
return nil, err
|
||||
@@ -86,5 +92,14 @@ func LoadSettings() (*Settings, error) {
|
||||
if err := decoder.Decode(&settings); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if settings.LastExportPath == "" {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
homeDir = "."
|
||||
}
|
||||
settings.LastExportPath = homeDir
|
||||
}
|
||||
|
||||
return &settings, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user