Skip to content

Commit

Permalink
refactor borders
Browse files Browse the repository at this point in the history
Signed-off-by: Aleksey Sviridkin <a.sviridkin@sdventures.com>
  • Loading branch information
Aleksey Sviridkin committed Jun 2, 2023
1 parent a3e9d21 commit 764f64d
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 37 deletions.
13 changes: 13 additions & 0 deletions build/borders/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

# Build for Windows (amd64)
env GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o borders-windows-amd64.exe main.go
upx --lzma --best borders-windows-amd64.exe

# Build for Mac (amd64)
env GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -o borders-mac-amd64 main.go
upx --lzma --best borders-mac-amd64

# Build for Mac (arm64)
env GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w" -o borders-mac-arm64 main.go
upx --lzma --best borders-mac-arm64
103 changes: 66 additions & 37 deletions cmd/borders/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ import (
func main() {
cmd.Execute()

// Validate input. Additional border can't be less than 0, but can be more than 100.
if cmd.AdditionalBorder < 0 {
log.Fatal("additional border can't be less than 0")
}

var (
borderClr = convertStringToColor(cmd.BorderColor)
err error
Expand All @@ -68,7 +73,7 @@ func main() {

err = AddBorderToImage(file, cmd.Prefix, borderClr, cmd.AdditionalBorder)
if err != nil {
log.Fatal(err)
log.Printf("failed to add border to %s: %v", file, err)
}
}
}
Expand All @@ -92,43 +97,13 @@ func AddBorderToImage(filePath, prefix string, borderColor color.Color, percent
return errors.Wrap(err, "failed to decode JPEG")
}

// Create the new image with a border.
borderSize := max(img.Bounds().Dx(), img.Bounds().Dy())
extraSpace := borderSize * percent / 100
newSize := borderSize + 2*extraSpace
newImage := image.NewRGBA(image.Rect(0, 0, newSize, newSize))

// Fill the image with the border color.
for x := 0; x < newSize; x++ {
for y := 0; y < newSize; y++ {
newImage.Set(x, y, borderColor)
}
}

// Copy the old image into the center of the new one.
rect := img.Bounds()
rect = rect.Add(image.Pt((newSize-rect.Dx())/2, (newSize-rect.Dy())/2))
draw.Draw(newImage, rect, img, image.Point{}, draw.Over)
// Calculate the new image size.
newImage := generateImageWithBorder(img, borderColor, percent)

// Generate file name for the new image.
// absolute directory path + prefix + file name + color + extension
absParantDir, err := filepath.Abs(filepath.Dir(filePath))
// Create a new file name.
newFileName, err := generateNewFileName(filePath, prefix)
if err != nil {
return errors.Wrap(err, "failed to get absolute path")
}

fileName := strings.TrimSuffix(filepath.Base(filePath), filepath.Ext(filePath))

newFileName := absParantDir + "/" + prefix + "_" + fileName + "_" + cmd.BorderColor + ".jpg"

// If file with the same name exists, add a number to the end of the file name.
if _, err := os.Stat(newFileName); err == nil {
for i := 1; ; i++ {
newFileName = absParantDir + "/" + prefix + "_" + fileName + "_" + cmd.BorderColor + "_" + strconv.Itoa(i) + ".jpg"
if _, err := os.Stat(newFileName); os.IsNotExist(err) {
break
}
}
return errors.Wrap(err, "failed to generate new file name")
}

// Open a file for writing.
Expand All @@ -139,7 +114,12 @@ func AddBorderToImage(filePath, prefix string, borderColor color.Color, percent
defer outputFile.Close()

// Encode the new image to JPEG and write it to the file.
return errors.Wrap(jpeg.Encode(outputFile, newImage, nil), "failed to encode JPEG")
err = jpeg.Encode(outputFile, newImage, &jpeg.Options{Quality: 100})
if err != nil {
return errors.Wrap(err, "failed to encode JPEG")
}

return nil
}

func max(a, b int) int {
Expand All @@ -151,6 +131,7 @@ func max(a, b int) int {
}

// convertStringToColor converts a string to a color.Color.
// It returns white if the string is not recognized.
func convertStringToColor(colorString string) color.Color {
colorMap := map[string]color.RGBA{
"white": {255, 255, 255, 255},
Expand Down Expand Up @@ -210,3 +191,51 @@ func getAllJPGFiles(dirPath string) ([]string, error) {

return files, nil
}

// generateImageWithBorder generates a new image with a border.
func generateImageWithBorder(img image.Image, borderColor color.Color, paspartuPercent int) image.Image {
// Create the new image with a border.
borderSize := max(img.Bounds().Dx(), img.Bounds().Dy())
extraSpace := borderSize * paspartuPercent / 100
newSize := borderSize + 2*extraSpace
newImage := image.NewRGBA(image.Rect(0, 0, newSize, newSize))

// Fill the image with the border color.
for x := 0; x < newSize; x++ {
for y := 0; y < newSize; y++ {
newImage.Set(x, y, borderColor)
}
}

// Copy the old image into the center of the new one.
rect := img.Bounds()
rect = rect.Add(image.Pt((newSize-rect.Dx())/2, (newSize-rect.Dy())/2))
draw.Draw(newImage, rect, img, image.Point{}, draw.Over)

return newImage
}

// generateNewFileName generates a new file name for the new image.
func generateNewFileName(filePath, prefix string) (string, error) {
// Generate file name for the new image.
absParantDir, err := filepath.Abs(filepath.Dir(filePath))
if err != nil {
return "", errors.Wrap(err, "failed to get absolute path")
}

fileName := strings.TrimSuffix(filepath.Base(filePath), filepath.Ext(filePath))

newFileName := absParantDir + "/" + prefix + "_" + fileName + "_" + cmd.BorderColor + ".jpg"

// If file with the same name exists, add a number to the end of the file name.
if _, err := os.Stat(newFileName); err == nil {
for i := 1; ; i++ {
newFileName = absParantDir + "/" + prefix + "_" + fileName + "_" + cmd.BorderColor + "_" + strconv.Itoa(i) + ".jpg"
if _, err := os.Stat(newFileName); os.IsNotExist(err) {
break
}
}
}

return newFileName, nil
}

0 comments on commit 764f64d

Please sign in to comment.