Refactored code, changed resize library
This commit is contained in:
parent
1c8b009dd1
commit
f5ffd897ca
35
README.md
35
README.md
|
|
@ -84,7 +84,6 @@ Visit [the app's snap store listing](https://snapcraft.io/ascii-image-converter)
|
|||
|
||||
### Go
|
||||
|
||||
For installing through Go
|
||||
```
|
||||
go install github.com/TheZoraiz/ascii-image-converter@latest
|
||||
```
|
||||
|
|
@ -398,23 +397,15 @@ func main() {
|
|||
flags := aic_package.DefaultFlags()
|
||||
|
||||
// This part is optional.
|
||||
// You can directly pass default flags variable to Convert() if you wish.
|
||||
// For clarity, all flags are covered in this example, but you can use specific ones.
|
||||
flags.Complex = false // Use complex character set
|
||||
flags.Dimensions = []int{50, 25} // 50 by 25 ascii art size
|
||||
flags.SaveTxtPath = "." // Save generated text in same directory
|
||||
flags.SaveImagePath = "." // Save generated PNG image in same directory
|
||||
flags.SaveGifPath = "." // If gif is provided, save ascii art gif in same directory
|
||||
flags.Negative = false // Ascii art will have negative color-depth
|
||||
flags.Colored = true // Keep colors from original image. This overrides flags.Grayscale and flags.FontColor
|
||||
flags.Grayscale = false // Returns grayscale ascii art. This overrides flags.FontColor
|
||||
flags.CustomMap = " .-=+#@" // Starting from darkest to brightest shades. This overrides flags.Complex
|
||||
flags.FlipX = false // Flips ascii art horizontally
|
||||
flags.FlipY = false // Flips ascii art vertically
|
||||
flags.Full = false // Display ascii art that fills the terminal width. This overrides flags.Dimensions
|
||||
flags.FontFilePath = "./RobotoMono-Regular.ttf" // File path to font .ttf file for saved png and gif files. Ignored if flags.SaveImagePath or flags.SaveGifPath are not set
|
||||
flags.FontColor = [3]int{0, 0, 0} // Font color for terminal and saved png and gif files.
|
||||
flags.SaveBackgroundColor = [3]int{255, 255, 255} // Font color for saved png and gif files. Ignored if flags.SaveImagePath or flags.SaveGifPath are not set.
|
||||
// You can directly pass default flags variable to aic_package.Convert() if you wish.
|
||||
// There are more flags, but these are the ones shown for demonstration
|
||||
flags.Dimensions = []int{50, 25}
|
||||
flags.Colored = true
|
||||
flags.SaveTxtPath = "."
|
||||
flags.SaveImagePath = "."
|
||||
flags.CustomMap = " .-=+#@"
|
||||
flags.FontFilePath = "./RobotoMono-Regular.ttf" // If file is in current directory
|
||||
flags.SaveBackgroundColor = [3]int{50, 50, 50}
|
||||
|
||||
// Conversion for an image
|
||||
asciiArt, err := aic_package.Convert(filePath, flags)
|
||||
|
|
@ -424,9 +415,13 @@ func main() {
|
|||
|
||||
fmt.Printf("%v\n", asciiArt)
|
||||
|
||||
// -----
|
||||
// GIF CONVERSION IS AN EXPERIMENTAL FEATURE
|
||||
// For a gif. This function may run infinitely, depending on the gif
|
||||
// Work needs to be done on gif conversion to be more library-compatible
|
||||
|
||||
filePath = "myGif.gif"
|
||||
|
||||
_, err := aic_package.Convert(filePath, flags)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
|
|
@ -450,7 +445,7 @@ You can fork the project and implement any changes you want for a pull request.
|
|||
|
||||
[github.com/nathan-fiscaletti/consolesize-go](https://github.com/nathan-fiscaletti/consolesize-go)
|
||||
|
||||
[github.com/nfnt/resize](https://github.com/nfnt/resize)
|
||||
[github.com/disintegration/imaging](https://github.com/disintegration/imaging)
|
||||
|
||||
[github.com/gookit/color](https://github.com/gookit/color)
|
||||
|
||||
|
|
@ -458,4 +453,4 @@ You can fork the project and implement any changes you want for a pull request.
|
|||
|
||||
## License
|
||||
|
||||
[Apache-2.0](https://github.com/TheZoraiz/ascii-image-converter/blob/master/LICENSE.txt)
|
||||
[Apache-2.0](https://github.com/TheZoraiz/ascii-image-converter/blob/master/LICENSE.txt)
|
||||
|
|
@ -56,6 +56,7 @@ type Flags struct {
|
|||
Grayscale bool
|
||||
|
||||
// Pass custom ascii art characters as a string.
|
||||
// e.g. " .-=+#@".
|
||||
// This overrides Flags.Complex
|
||||
CustomMap string
|
||||
|
||||
|
|
|
|||
5
go.mod
5
go.mod
|
|
@ -4,6 +4,7 @@ go 1.16
|
|||
|
||||
require (
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/fogleman/gg v1.3.0
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
|
||||
|
|
@ -12,15 +13,13 @@ require (
|
|||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/mitchellh/mapstructure v1.4.1 // indirect
|
||||
github.com/nathan-fiscaletti/consolesize-go v0.0.0-20210105204122-a87d9f614b9d
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/pelletier/go-toml v1.9.1 // indirect
|
||||
github.com/spf13/afero v1.6.0 // indirect
|
||||
github.com/spf13/cast v1.3.1 // indirect
|
||||
github.com/spf13/cobra v1.1.3
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/viper v1.7.1
|
||||
golang.org/x/image v0.0.0-20210504121937-7319ad40d33e
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
|
||||
golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||
)
|
||||
|
|
|
|||
9
go.sum
9
go.sum
|
|
@ -38,6 +38,8 @@ 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=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
|
||||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
|
|
@ -142,8 +144,6 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
|
|||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nathan-fiscaletti/consolesize-go v0.0.0-20210105204122-a87d9f614b9d h1:PQW4Aqovdqc9efHl9EVA+bhKmuZ4ME1HvSYYDvaDiK0=
|
||||
github.com/nathan-fiscaletti/consolesize-go v0.0.0-20210105204122-a87d9f614b9d/go.mod h1:cxIIfNMTwff8f/ZvRouvWYF6wOoO7nj99neWSx2q/Es=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
|
|
@ -226,8 +226,9 @@ golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm0
|
|||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20210504121937-7319ad40d33e h1:PzJMNfFQx+QO9hrC1GwZ4BoPGeNGhfeQEgcQFArEjPk=
|
||||
golang.org/x/image v0.0.0-20210504121937-7319ad40d33e/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
|
|
|
|||
|
|
@ -23,91 +23,8 @@ import (
|
|||
)
|
||||
|
||||
// Reference taken from http://paulbourke.net/dataformats/asciiart/
|
||||
var asciiTableSimple = map[int]string{
|
||||
0: " ",
|
||||
1: ".",
|
||||
2: ":",
|
||||
3: "-",
|
||||
4: "=",
|
||||
5: "+",
|
||||
6: "*",
|
||||
7: "#",
|
||||
8: "%",
|
||||
9: "@",
|
||||
}
|
||||
|
||||
// Reference taken from http://paulbourke.net/dataformats/asciiart/
|
||||
var asciiTableDetailed = map[int]string{
|
||||
0: " ",
|
||||
1: ".",
|
||||
2: "'",
|
||||
3: "`",
|
||||
4: "^",
|
||||
5: "\"",
|
||||
6: ",",
|
||||
7: ":",
|
||||
8: ";",
|
||||
9: "I",
|
||||
10: "l",
|
||||
11: "!",
|
||||
12: "i",
|
||||
13: ">",
|
||||
14: "<",
|
||||
15: "~",
|
||||
16: "+",
|
||||
17: "_",
|
||||
18: "-",
|
||||
19: "?",
|
||||
20: "]",
|
||||
21: "[",
|
||||
22: "}",
|
||||
23: "{",
|
||||
24: "1",
|
||||
25: ")",
|
||||
26: "(",
|
||||
27: "|",
|
||||
28: "/",
|
||||
29: "t",
|
||||
30: "f",
|
||||
31: "j",
|
||||
32: "r",
|
||||
33: "x",
|
||||
34: "n",
|
||||
35: "u",
|
||||
36: "v",
|
||||
37: "c",
|
||||
38: "z",
|
||||
39: "X",
|
||||
40: "Y",
|
||||
41: "U",
|
||||
42: "J",
|
||||
43: "C",
|
||||
44: "L",
|
||||
45: "Q",
|
||||
46: "0",
|
||||
47: "O",
|
||||
48: "Z",
|
||||
49: "m",
|
||||
50: "w",
|
||||
51: "q",
|
||||
52: "p",
|
||||
53: "d",
|
||||
54: "b",
|
||||
55: "k",
|
||||
56: "h",
|
||||
57: "a",
|
||||
58: "o",
|
||||
59: "*",
|
||||
60: "#",
|
||||
61: "M",
|
||||
62: "W",
|
||||
63: "&",
|
||||
64: "8",
|
||||
65: "%",
|
||||
66: "B",
|
||||
67: "@",
|
||||
68: "$",
|
||||
}
|
||||
var asciiTableSimple = " .:-=+*#%@"
|
||||
var asciiTableDetailed = " .'`^\",:;Il!i><~+_-?][}{1)(|\\/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$"
|
||||
|
||||
// For each individual element of imgSet in ConvertToASCIISlice()
|
||||
const MAX_VAL float64 = 65535
|
||||
|
|
@ -119,24 +36,34 @@ type AsciiChar struct {
|
|||
RgbValue [3]uint32
|
||||
}
|
||||
|
||||
// Converts the 2D image_conversions.AsciiPixel slice of image data (each instance representing each compressed pixel of original image)
|
||||
// to a 2D image_conversions.AsciiChar slice
|
||||
//
|
||||
// If complex parameter is true, values are compared to 69 levels of color density in ASCII characters.
|
||||
// Otherwise, values are compared to 10 levels of color density in ASCII characters.
|
||||
/*
|
||||
Converts the 2D image_conversions.AsciiPixel slice of image data (each instance representing each compressed pixel of original image)
|
||||
to a 2D image_conversions.AsciiChar slice
|
||||
|
||||
If complex parameter is true, values are compared to 70 levels of color density in ASCII characters.
|
||||
Otherwise, values are compared to 10 levels of color density in ASCII characters.
|
||||
*/
|
||||
func ConvertToAsciiChars(imgSet [][]AsciiPixel, negative, colored, complex bool, customMap string, fontColor [3]int) [][]AsciiChar {
|
||||
|
||||
height := len(imgSet)
|
||||
width := len(imgSet[0])
|
||||
|
||||
var chosenTable map[int]string
|
||||
chosenTable := map[int]string{}
|
||||
|
||||
// Turn ascii character-set string into map[int]string{} literal
|
||||
if customMap == "" {
|
||||
var charSet string
|
||||
|
||||
if complex {
|
||||
chosenTable = asciiTableDetailed
|
||||
charSet = asciiTableDetailed
|
||||
} else {
|
||||
chosenTable = asciiTableSimple
|
||||
charSet = asciiTableSimple
|
||||
}
|
||||
|
||||
for index, char := range charSet {
|
||||
chosenTable[index] = string(char)
|
||||
}
|
||||
|
||||
} else {
|
||||
chosenTable = map[int]string{}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import (
|
|||
"image/color"
|
||||
|
||||
"github.com/TheZoraiz/ascii-image-converter/aic_package/winsize"
|
||||
"github.com/nfnt/resize"
|
||||
"github.com/disintegration/imaging"
|
||||
)
|
||||
|
||||
type AsciiPixel struct {
|
||||
|
|
@ -31,12 +31,14 @@ type AsciiPixel struct {
|
|||
rgbValue [3]uint32
|
||||
}
|
||||
|
||||
// This function shrinks the passed image according to passed dimensions or terminal
|
||||
// size if none are passed. Stores each pixel's grayscale and RGB values in an AsciiPixel
|
||||
// instance to simplify getting numeric data for ASCII character comparison.
|
||||
//
|
||||
// The returned 2D AsciiPixel slice contains each corresponding pixel's values. Grayscale value
|
||||
// ranges from 0 to 65535, while RGB values are separate.
|
||||
/*
|
||||
This function shrinks the passed image according to passed dimensions or terminal
|
||||
size if none are passed. Stores each pixel's grayscale and RGB values in an AsciiPixel
|
||||
instance to simplify getting numeric data for ASCII character comparison.
|
||||
|
||||
The returned 2D AsciiPixel slice contains each corresponding pixel's values. Grayscale value
|
||||
ranges from 0 to 65535, while RGB values are separate.
|
||||
*/
|
||||
func ConvertToAsciiPixels(img image.Image, dimensions []int, width, height int, flipX, flipY, full bool) ([][]AsciiPixel, error) {
|
||||
|
||||
var asciiWidth, asciiHeight int
|
||||
|
|
@ -51,13 +53,13 @@ func ConvertToAsciiPixels(img image.Image, dimensions []int, width, height int,
|
|||
asciiWidth = terminalWidth - 1
|
||||
|
||||
// Passing 0 in place of width keeps the original image's aspect ratio
|
||||
smallImg = resize.Resize(uint(asciiWidth), 0, img, resize.Lanczos3)
|
||||
smallImg = imaging.Resize(img, asciiWidth, 0, imaging.Lanczos)
|
||||
asciiHeight = smallImg.Bounds().Max.Y - smallImg.Bounds().Min.Y
|
||||
|
||||
// To fix aspect ratio in eventual ascii art
|
||||
asciiHeight = int(0.5 * float32(asciiHeight))
|
||||
|
||||
smallImg = resize.Resize(uint(asciiWidth), uint(asciiHeight), img, resize.Lanczos3)
|
||||
smallImg = imaging.Resize(img, asciiWidth, asciiHeight, imaging.Lanczos)
|
||||
|
||||
} else if (width != 0 || height != 0) && len(dimensions) == 0 {
|
||||
// If either width or height is set and dimensions aren't given
|
||||
|
|
@ -71,7 +73,7 @@ func ConvertToAsciiPixels(img image.Image, dimensions []int, width, height int,
|
|||
|
||||
asciiWidth = width
|
||||
|
||||
smallImg = resize.Resize(uint(asciiWidth), 0, img, resize.Lanczos3)
|
||||
smallImg = imaging.Resize(img, asciiWidth, 0, imaging.Lanczos)
|
||||
asciiHeight = smallImg.Bounds().Max.Y - smallImg.Bounds().Min.Y
|
||||
|
||||
asciiHeight = int(0.5 * float32(asciiHeight))
|
||||
|
|
@ -79,14 +81,14 @@ func ConvertToAsciiPixels(img image.Image, dimensions []int, width, height int,
|
|||
asciiHeight = 1
|
||||
}
|
||||
|
||||
smallImg = resize.Resize(uint(asciiWidth), uint(asciiHeight), img, resize.Lanczos3)
|
||||
smallImg = imaging.Resize(img, asciiWidth, asciiHeight, imaging.Lanczos)
|
||||
|
||||
} else if height != 0 && width == 0 {
|
||||
// If height is set and width is not set, use height to calculate aspect ratio
|
||||
|
||||
asciiHeight = height
|
||||
|
||||
smallImg = resize.Resize(0, uint(asciiHeight), img, resize.Lanczos3)
|
||||
smallImg = imaging.Resize(img, 0, asciiHeight, imaging.Lanczos)
|
||||
asciiWidth = smallImg.Bounds().Max.X - smallImg.Bounds().Min.X
|
||||
|
||||
asciiWidth = int(2 * float32(asciiWidth))
|
||||
|
|
@ -95,7 +97,7 @@ func ConvertToAsciiPixels(img image.Image, dimensions []int, width, height int,
|
|||
return nil, fmt.Errorf("width calculated with aspect ratio exceeds terminal width")
|
||||
}
|
||||
|
||||
smallImg = resize.Resize(uint(asciiWidth), uint(asciiHeight), img, resize.Lanczos3)
|
||||
smallImg = imaging.Resize(img, asciiWidth, asciiHeight, imaging.Lanczos)
|
||||
|
||||
} else {
|
||||
return nil, fmt.Errorf("both width and height can't be set. Use dimensions instead")
|
||||
|
|
@ -106,7 +108,7 @@ func ConvertToAsciiPixels(img image.Image, dimensions []int, width, height int,
|
|||
|
||||
asciiHeight = terminalHeight - 1
|
||||
|
||||
smallImg = resize.Resize(0, uint(asciiHeight), img, resize.Lanczos3)
|
||||
smallImg = imaging.Resize(img, 0, asciiHeight, imaging.Lanczos)
|
||||
asciiWidth = smallImg.Bounds().Max.X - smallImg.Bounds().Min.X
|
||||
|
||||
// To fix aspect ratio in eventual ascii art
|
||||
|
|
@ -116,7 +118,7 @@ func ConvertToAsciiPixels(img image.Image, dimensions []int, width, height int,
|
|||
if asciiWidth >= terminalWidth {
|
||||
asciiWidth = terminalWidth - 1
|
||||
|
||||
smallImg = resize.Resize(uint(asciiWidth), 0, img, resize.Lanczos3)
|
||||
smallImg = imaging.Resize(img, asciiWidth, 0, imaging.Lanczos)
|
||||
|
||||
asciiHeight = smallImg.Bounds().Max.Y - smallImg.Bounds().Min.Y
|
||||
|
||||
|
|
@ -124,12 +126,12 @@ func ConvertToAsciiPixels(img image.Image, dimensions []int, width, height int,
|
|||
asciiHeight = int(0.5 * float32(asciiHeight))
|
||||
}
|
||||
|
||||
smallImg = resize.Resize(uint(asciiWidth), uint(asciiHeight), img, resize.Lanczos3)
|
||||
smallImg = imaging.Resize(img, asciiWidth, asciiHeight, imaging.Lanczos)
|
||||
|
||||
} else {
|
||||
asciiWidth = dimensions[0]
|
||||
asciiHeight = dimensions[1]
|
||||
smallImg = resize.Resize(uint(asciiWidth), uint(asciiHeight), img, resize.Lanczos3)
|
||||
smallImg = imaging.Resize(img, asciiWidth, asciiHeight, imaging.Lanczos)
|
||||
}
|
||||
|
||||
// Repeated despite being in cmd/root.go to maintain support for library
|
||||
|
|
|
|||
Loading…
Reference in New Issue