You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
4.1 KiB
187 lines
4.1 KiB
package main |
|
|
|
// imports |
|
import ( |
|
"encoding/json" |
|
"flag" |
|
"fmt" |
|
"image" |
|
_ "image/jpeg" |
|
"image/png" |
|
"io" |
|
"log" |
|
"math/rand" |
|
"net/http" |
|
"os" |
|
"time" |
|
|
|
"github.com/kbinani/screenshot" |
|
"github.com/reujab/wallpaper" |
|
) |
|
|
|
var ( |
|
sourceImgName string |
|
outputImgName string |
|
useNasa bool |
|
useRandom bool |
|
setWallpaper bool |
|
useSketch bool |
|
nasaAPI string |
|
totalCycleCount = 5000 |
|
) |
|
|
|
func init() { |
|
flag.BoolVar(&useNasa, "nasa", false, "Use NASA Astronomy Pic Of the Day as a source image") |
|
flag.BoolVar(&setWallpaper, "set", false, "Set user wallpaper to the output.") |
|
flag.BoolVar(&useRandom, "unsplash", false, "Use random unsplash image for seed (Will grab dimensions from background or source if set)") |
|
flag.BoolVar(&useSketch, "sketch", false, "Use Sketch to generate a new image.") |
|
flag.StringVar(&sourceImgName, "source", "", "Source image, will override current background") |
|
flag.StringVar(&outputImgName, "output", "out.png", "Output image filename") |
|
flag.StringVar(&nasaAPI, "nasa-key", "DEMO_KEY", "Supply your own API Key for NASA APOD") |
|
} |
|
|
|
func main() { |
|
flag.Parse() |
|
background, err := wallpaper.Get() |
|
if err != nil { |
|
log.Panicln(err) |
|
} |
|
bounds := screenshot.GetDisplayBounds(0) |
|
|
|
var img image.Image |
|
if useRandom { |
|
img, err = loadRandomUnsplashImage(bounds.Dx(), bounds.Dy()) |
|
if err != nil { |
|
log.Panicln(err) |
|
} |
|
} else if useNasa { |
|
resp, err := http.Get(fmt.Sprintf("https://api.nasa.gov/planetary/apod?api_key=%+v", nasaAPI)) |
|
if err != nil { |
|
log.Fatalf("\nUnable to get NASA API Response\n") |
|
return |
|
} |
|
var apod APODResponse |
|
decoder := json.NewDecoder(resp.Body) |
|
err = decoder.Decode(&apod) |
|
if err != nil { |
|
log.Fatalf("\nUnable to decode APOD Response: \n%+v\n", resp) |
|
return |
|
} |
|
file, err := os.CreateTemp(".", apod.Hdurl) |
|
if err != nil { |
|
log.Panicln(err) |
|
} |
|
defer os.Remove(file.Name()) |
|
downloadFile(file.Name(), apod.Hdurl) |
|
img, err = loadImage(file.Name()) |
|
if err != nil { |
|
log.Panicln(err) |
|
} |
|
} else if len(sourceImgName) > 0 { |
|
img, err = loadImage(sourceImgName) |
|
if err != nil { |
|
log.Panicln(err) |
|
} |
|
} else { |
|
img, err = loadImage(background) |
|
if err != nil { |
|
log.Println(background) |
|
log.Panicln(err) |
|
} |
|
} |
|
|
|
s := NewSketch(img, UserParams{ |
|
StrokeRatio: 0.75, |
|
DestWidth: bounds.Dx(), |
|
DestHeight: bounds.Dy(), |
|
InitialAlpha: 0.1, |
|
StrokeReduction: 0.002, |
|
AlphaIncrease: 0.06, |
|
StrokeInversionThreshold: 0.05, |
|
StrokeJitter: int(0.1 * float64(bounds.Dx())), |
|
MinEdgeCount: 3, |
|
MaxEdgeCount: 8, |
|
}) |
|
|
|
rand.Seed(time.Now().Unix()) |
|
|
|
if useSketch { |
|
for i := 0; i < totalCycleCount; i++ { |
|
s.Update() |
|
} |
|
|
|
saveOutput(s.Output(), outputImgName) |
|
} else { |
|
|
|
saveOutput(img, outputImgName) |
|
} |
|
|
|
if setWallpaper { |
|
err = wallpaper.SetFromFile(outputImgName) |
|
if err != nil { |
|
log.Panicln(err) |
|
} |
|
} |
|
} |
|
|
|
func loadRandomUnsplashImage(width, height int) (image.Image, error) { |
|
url := fmt.Sprintf("https://source.unsplash.com/random/%dx%d", width, height) |
|
res, err := http.Get(url) |
|
if err != nil { |
|
return nil, err |
|
} |
|
defer res.Body.Close() |
|
|
|
img, _, err := image.Decode(res.Body) |
|
return img, err |
|
} |
|
|
|
func loadImage(src string) (image.Image, error) { |
|
file, _ := os.Open(sourceImgName) |
|
defer file.Close() |
|
img, _, err := image.Decode(file) |
|
return img, err |
|
} |
|
|
|
func saveOutput(img image.Image, filePath string) error { |
|
f, err := os.Create(filePath) |
|
if err != nil { |
|
return err |
|
} |
|
defer f.Close() |
|
|
|
// Encode to `PNG` with `DefaultCompression` level |
|
// then save to file |
|
err = png.Encode(f, img) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
return nil |
|
} |
|
|
|
// https://stackoverflow.com/questions/33845770/how-do-i-download-a-file-with-a-http-request-in-go-language/33845771 |
|
func downloadFile(filepath string, url string) (err error) { |
|
|
|
// Create the file |
|
out, err := os.Create(filepath) |
|
if err != nil { |
|
return err |
|
} |
|
defer out.Close() |
|
|
|
// Get the data |
|
resp, err := http.Get(url) |
|
if err != nil { |
|
return err |
|
} |
|
defer resp.Body.Close() |
|
|
|
// Writer the body to file |
|
_, err = io.Copy(out, resp.Body) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
return nil |
|
}
|
|
|