Initial working version.
This commit is contained in:
parent
4b7435c523
commit
eac2f17c8f
7 changed files with 225 additions and 0 deletions
26
app.go
Normal file
26
app.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2020 Gytis Repečka (gytis@repecka.com)
|
||||||
|
*
|
||||||
|
* This file is part of webimg.
|
||||||
|
*
|
||||||
|
* webimg is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, included
|
||||||
|
* in the LICENSE file in this source code package.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package webimg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FormatVersion constructs the version string for the application
|
||||||
|
func FormatVersion() string {
|
||||||
|
// return serverSoftware + " " + softwareVer
|
||||||
|
return "gowebimg 0.0.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
// OutputVersion prints out the version of the application.
|
||||||
|
func OutputVersion() {
|
||||||
|
fmt.Println(FormatVersion())
|
||||||
|
}
|
4
cmd/webimg/.gitignore
vendored
Normal file
4
cmd/webimg/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
webimg
|
||||||
|
webimg.exe
|
||||||
|
webimg.log
|
||||||
|
|
99
cmd/webimg/main.go
Normal file
99
cmd/webimg/main.go
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2020 Gytis Repečka (gytis@repecka.com)
|
||||||
|
*
|
||||||
|
* This file is part of webimg.
|
||||||
|
*
|
||||||
|
* webimg is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, included
|
||||||
|
* in the LICENSE file in this source code package.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.gyt.is/webimg"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// webimg.PrintHello()
|
||||||
|
|
||||||
|
// Set some parameters
|
||||||
|
timestampLayout := "2006-01-02 15:04:05.000 (MST Z07:00)"
|
||||||
|
currentTime := time.Now()
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
logFile, err := os.OpenFile("webimg.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer logFile.Close()
|
||||||
|
log.SetOutput(logFile)
|
||||||
|
|
||||||
|
// Log beginning of program
|
||||||
|
log.Printf("Started webimg: %s.\n", currentTime.Format(timestampLayout))
|
||||||
|
|
||||||
|
cmdLineArgs := os.Args
|
||||||
|
/*
|
||||||
|
Subcommands
|
||||||
|
Args[0] - executable path;
|
||||||
|
Args[1] - subcommand.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Main subcommands
|
||||||
|
watermarkCommand := flag.NewFlagSet("watermark", flag.ExitOnError)
|
||||||
|
|
||||||
|
// Subcommand "watermark" flag pointers
|
||||||
|
watermarkImagePtr := watermarkCommand.String("image", "", "Path to image (JPG) file to watermark.")
|
||||||
|
|
||||||
|
// General options usable with other commands
|
||||||
|
outputVersion := flag.Bool("v", false, "Output the current version")
|
||||||
|
outputHelp := flag.Bool("h", false, "Show help information")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if *outputVersion {
|
||||||
|
webimg.OutputVersion()
|
||||||
|
os.Exit(0)
|
||||||
|
} else if *outputHelp {
|
||||||
|
fmt.Println("General commands:")
|
||||||
|
flag.PrintDefaults()
|
||||||
|
fmt.Println("Watermark commands:")
|
||||||
|
watermarkCommand.PrintDefaults()
|
||||||
|
|
||||||
|
// Check if subcommand (watermark) was provided
|
||||||
|
} else if len(cmdLineArgs) >= 2 {
|
||||||
|
// Switch based on subcommand
|
||||||
|
switch cmdLineArgs[1] {
|
||||||
|
case "watermark":
|
||||||
|
watermarkCommand.Parse(cmdLineArgs[2:])
|
||||||
|
|
||||||
|
if *watermarkImagePtr != "" {
|
||||||
|
imageToWatermark := fmt.Sprintf("%s", *watermarkImagePtr)
|
||||||
|
fmt.Printf("Image to watermark: %s\n", imageToWatermark)
|
||||||
|
|
||||||
|
// Input image, watermark image, result image, bottom-right offset X, bottom-right offset Y, watermark alpha
|
||||||
|
doWatermark := webimg.Watermark(imageToWatermark, "watermark_inretio-logo.png", "result_img.jpg", 30, 30, 70)
|
||||||
|
if doWatermark != nil {
|
||||||
|
fmt.Println("There was an error watermarking image...")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("No image given to watermark!")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
fmt.Println("Wrong subcommand provided!")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("No work given. Holiday time!")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log end of program
|
||||||
|
// time.Sleep(2 * time.Second)
|
||||||
|
currentTime = time.Now()
|
||||||
|
log.Printf("Finished webimg: %s.\n", currentTime.Format(timestampLayout))
|
||||||
|
log.Println("--------------------")
|
||||||
|
}
|
BIN
cmd/webimg/result_img.jpg
Normal file
BIN
cmd/webimg/result_img.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
BIN
cmd/webimg/smplayer_preferences.jpg
Normal file
BIN
cmd/webimg/smplayer_preferences.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
BIN
cmd/webimg/watermark_inretio-logo.png
Normal file
BIN
cmd/webimg/watermark_inretio-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.9 KiB |
96
watermark.go
Normal file
96
watermark.go
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2020 Gytis Repečka (gytis@repecka.com)
|
||||||
|
*
|
||||||
|
* This file is part of webimg.
|
||||||
|
*
|
||||||
|
* webimg is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, included
|
||||||
|
* in the LICENSE file in this source code package.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package webimg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
|
"image/jpeg"
|
||||||
|
"image/png"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PrintHello() {
|
||||||
|
fmt.Println("Hello there!")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Watermark(imagePath, watermarkPath, resultPath string, offsetX, offsetY int, watermarkAlpha uint8) (err error) {
|
||||||
|
// Input image
|
||||||
|
// To-do: need to sanitize image paths!
|
||||||
|
image1, err := os.Open(imagePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to open: %s", err)
|
||||||
|
}
|
||||||
|
first, err := jpeg.Decode(image1)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to decode: %s", err)
|
||||||
|
}
|
||||||
|
defer image1.Close()
|
||||||
|
|
||||||
|
// Watermark image
|
||||||
|
image2, err := os.Open(watermarkPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to open: %s", err)
|
||||||
|
}
|
||||||
|
second, err := png.Decode(image2)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to decode: %s", err)
|
||||||
|
}
|
||||||
|
defer image2.Close()
|
||||||
|
|
||||||
|
// x, y from top-left corner
|
||||||
|
// offset := image.Pt(100, 50)
|
||||||
|
// log.Printf("Point: %V (%T)\n", offset, offset)
|
||||||
|
|
||||||
|
// Bounds of input image
|
||||||
|
inBounds := first.Bounds()
|
||||||
|
// Bounds of watermark image
|
||||||
|
watermarkBounds := second.Bounds()
|
||||||
|
|
||||||
|
// To-do: offset should be configurable!
|
||||||
|
watermarkCoordX1 := inBounds.Max.X - offsetX - watermarkBounds.Max.X // Input image x2 - offset x - watermark x2
|
||||||
|
watermarkCoordY1 := inBounds.Max.Y - offsetY - watermarkBounds.Max.Y // Input image y2 - offset y - watermark y2
|
||||||
|
|
||||||
|
offset := image.Pt(watermarkCoordX1, watermarkCoordY1)
|
||||||
|
|
||||||
|
outBoundsOff := watermarkBounds.Add(offset)
|
||||||
|
// outBoundsOff := inBounds.Sub(offset)
|
||||||
|
/*
|
||||||
|
log.Printf("Bounds (input): %V (%T)\n", inBounds, inBounds)
|
||||||
|
log.Printf("Bounds (watermark): %V (%T)\n", watermarkBounds, watermarkBounds)
|
||||||
|
log.Printf("Bounds (watermark with offset): %V (%T)\n", outBoundsOff, outBoundsOff)
|
||||||
|
*/
|
||||||
|
log.Printf("Watermark x1: %d, y1: %d, x2: %d, y2: %d.", outBoundsOff.Min.X, outBoundsOff.Min.Y, outBoundsOff.Max.X, outBoundsOff.Max.Y)
|
||||||
|
|
||||||
|
// Create new (output) image with size (bounds) of input image
|
||||||
|
image3 := image.NewRGBA(inBounds)
|
||||||
|
|
||||||
|
// Transparency
|
||||||
|
// 0 - 255
|
||||||
|
mask := image.NewUniform(color.Alpha{watermarkAlpha})
|
||||||
|
|
||||||
|
draw.Draw(image3, inBounds, first, image.ZP, draw.Src)
|
||||||
|
|
||||||
|
draw.DrawMask(image3, outBoundsOff, second, image.ZP, mask, image.ZP, draw.Over)
|
||||||
|
|
||||||
|
third, err := os.Create(resultPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to create: %s", err)
|
||||||
|
}
|
||||||
|
// jpeg.Encode(third, image3, &jpeg.Options{jpeg.DefaultQuality})
|
||||||
|
jpeg.Encode(third, image3, &jpeg.Options{85})
|
||||||
|
defer third.Close()
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
Loading…
Reference in a new issue