From 85a0b60d62bf6291b961aa2e3e7b40cc9525f8b0 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Sat, 21 Apr 2018 16:58:54 +0200 Subject: [PATCH] Added patch to remove borders from images --- pages/character/character.scarlet | 4 +- .../remove-character-borders.go | 159 ++++++++++++++++++ 2 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 patches/remove-character-borders/remove-character-borders.go diff --git a/pages/character/character.scarlet b/pages/character/character.scarlet index df09f31c..1229d86b 100644 --- a/pages/character/character.scarlet +++ b/pages/character/character.scarlet @@ -19,8 +19,8 @@ margin-bottom 1rem .character-image-large - width 225px - height 350px + width 219px + height 344px border-radius ui-element-border-radius box-shadow shadow-light diff --git a/patches/remove-character-borders/remove-character-borders.go b/patches/remove-character-borders/remove-character-borders.go new file mode 100644 index 00000000..cae35816 --- /dev/null +++ b/patches/remove-character-borders/remove-character-borders.go @@ -0,0 +1,159 @@ +package main + +import ( + "bytes" + "fmt" + "image" + "os" + "path" + "time" + + "github.com/animenotifier/arn" + "github.com/fatih/color" + + icolor "image/color" + _ "image/gif" + _ "image/jpeg" + "image/png" +) + +func main() { + defer color.Green("Finished.") + defer arn.Node.Close() + defer time.Sleep(time.Second) + + characters := arn.FilterCharacters(func(character *arn.Character) bool { + return character.HasImage() + }) + + for index, character := range characters { + fmt.Printf("[%d / %d] %s\n", index+1, len(characters), character) + process(character) + } +} + +func process(character *arn.Character) { + file, err := os.Open(path.Join(arn.Root, "images", "characters", "original", character.ID+character.Image.Extension)) + + if err != nil { + color.Red(err.Error()) + return + } + + defer file.Close() + + img, format, err := image.Decode(file) + + if err != nil { + color.Red(err.Error()) + return + } + + newImg := removeBorders(img) + + fmt.Println(img.Bounds().Dx(), img.Bounds().Dy(), format) + fmt.Println(newImg.Bounds().Dx(), newImg.Bounds().Dy()) + + buffer := bytes.NewBuffer(nil) + err = png.Encode(buffer, newImg) + + if err != nil { + color.Red(err.Error()) + return + } + + char, _ := arn.GetCharacter("EI3HwrmiRm") + char.SetImageBytes(buffer.Bytes()) + char.Save() +} + +func diffAbs(a uint32, b uint32) uint32 { + if a > b { + return a - b + } + + return b - a +} + +func removeBorders(img image.Image) image.Image { + const maxBorderLength = 3 + + width := img.Bounds().Dx() + height := img.Bounds().Dy() + + borderLength := 0 + + for ; borderLength < maxBorderLength; borderLength++ { + edgeColors := []icolor.Color{} + + // Top edge + for x := borderLength; x < width-borderLength*2; x++ { + c := img.At(x, borderLength) + edgeColors = append(edgeColors, c) + } + + // Bottom edge + for x := borderLength; x < width-borderLength*2; x++ { + c := img.At(x, height-borderLength-1) + edgeColors = append(edgeColors, c) + } + + // Left edge + for y := borderLength; y < height-borderLength*2; y++ { + c := img.At(borderLength, y) + edgeColors = append(edgeColors, c) + } + + // Right edge + for y := borderLength; y < height-borderLength*2; y++ { + c := img.At(width-borderLength-1, y) + edgeColors = append(edgeColors, c) + } + + // Check if all edge colors are similar. + // Find average color first. + totalR := uint64(0) + totalG := uint64(0) + totalB := uint64(0) + + for _, c := range edgeColors { + r, g, b, _ := c.RGBA() + totalR += uint64(r) + totalG += uint64(g) + totalB += uint64(b) + } + + averageR := uint32(totalR / uint64(len(edgeColors))) + averageG := uint32(totalG / uint64(len(edgeColors))) + averageB := uint32(totalB / uint64(len(edgeColors))) + + const tolerance = 11000 + + // Check if the colors are close to the average color + notSimilarCount := 0 + + for _, c := range edgeColors { + r, g, b, _ := c.RGBA() + + if diffAbs(r, averageR) > tolerance || diffAbs(g, averageG) > tolerance || diffAbs(b, averageB) > tolerance { + notSimilarCount++ + } + } + + if notSimilarCount >= 5 { + break + } + } + + newWidth := width - borderLength*2 + newHeight := height - borderLength*2 + newImg := image.NewNRGBA(image.Rect(0, 0, newWidth, newHeight)) + + for x := 0; x < newWidth; x++ { + for y := 0; y < newHeight; y++ { + newImg.Set(x, y, img.At(borderLength+x, borderLength+y)) + } + } + + return newImg +}