parent
dd8f65207e
commit
df5eafe9a3
|
|
@ -29,7 +29,6 @@ builds:
|
|||
# - mipsle
|
||||
# - mips64
|
||||
# - mips64le
|
||||
|
||||
|
||||
archives:
|
||||
-
|
||||
|
|
|
|||
|
|
@ -162,9 +162,9 @@ ascii-image-converter myImage.jpeg
|
|||
|
||||
#### --color OR -C
|
||||
|
||||
> **Note:** Your terminal must support 24-bit colors for appropriate results
|
||||
> **Note:** Your terminal must support 24-bit or 8-bit colors for appropriate results. If 24-bit colors aren't supported, 8-bit color escape codes will be used
|
||||
|
||||
Display ascii art with the colors from original image. Works with the --negative flag as well.
|
||||
Display ascii art with the colors from original image.
|
||||
|
||||
```
|
||||
ascii-image-converter [image paths/urls] -C
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ func pathIsGif(gifPath, urlImgName string, pathIsURl bool, urlImgBytes []byte, l
|
|||
// If a frame is found that is smaller than the first frame, then this gif contains smaller subimages that are
|
||||
// positioned inside the original gif. This behavior isn't supported by this app
|
||||
if firstGifFrameWidth != frameImage.Bounds().Dx() || firstGifFrameHeight != frameImage.Bounds().Dy() {
|
||||
fmt.Println("Error: GIF contains subimages smaller than default width and height\nProcess aborted because ascii-image-converter doesn't support subimage placement and transparency in GIFs\n")
|
||||
fmt.Printf("Error: GIF contains subimages smaller than default width and height\nProcess aborted because ascii-image-converter doesn't support subimage placement and transparency in GIFs\n\n")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
|
|
@ -99,16 +99,21 @@ func pathIsGif(gifPath, urlImgName string, pathIsURl bool, urlImgBytes []byte, l
|
|||
|
||||
imgSet, err = imgManip.ConvertToAsciiPixels(frameImage, dimensions, width, height, flipX, flipY, full, braille, dither, noTermSizeComparison)
|
||||
if err != nil {
|
||||
fmt.Println("Error:", err)
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
var asciiCharSet [][]imgManip.AsciiChar
|
||||
if braille {
|
||||
asciiCharSet = imgManip.ConvertToBrailleChars(imgSet, negative, colored, colorBg, fontColor, threshold)
|
||||
asciiCharSet, err = imgManip.ConvertToBrailleChars(imgSet, negative, colored, grayscale, colorBg, fontColor, threshold)
|
||||
} else {
|
||||
asciiCharSet = imgManip.ConvertToAsciiChars(imgSet, negative, colored, complex, colorBg, customMap, fontColor)
|
||||
asciiCharSet, err = imgManip.ConvertToAsciiChars(imgSet, negative, colored, grayscale, complex, colorBg, customMap, fontColor)
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
gifFramesSlice[i].asciiCharSet = asciiCharSet
|
||||
gifFramesSlice[i].delay = originalGif.Delay[i]
|
||||
|
||||
|
|
@ -187,7 +192,7 @@ func pathIsGif(gifPath, urlImgName string, pathIsURl bool, urlImgBytes []byte, l
|
|||
colored || grayscale,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println("Error:", err)
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,9 +51,12 @@ func pathIsImage(imagePath, urlImgName string, pathIsURl bool, urlImgBytes []byt
|
|||
var asciiSet [][]imgManip.AsciiChar
|
||||
|
||||
if braille {
|
||||
asciiSet = imgManip.ConvertToBrailleChars(imgSet, negative, colored, colorBg, fontColor, threshold)
|
||||
asciiSet, err = imgManip.ConvertToBrailleChars(imgSet, negative, colored, grayscale, colorBg, fontColor, threshold)
|
||||
} else {
|
||||
asciiSet = imgManip.ConvertToAsciiChars(imgSet, negative, colored, complex, colorBg, customMap, fontColor)
|
||||
asciiSet, err = imgManip.ConvertToAsciiChars(imgSet, negative, colored, grayscale, complex, colorBg, customMap, fontColor)
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Save ascii art as .png image before printing it, if --save-img flag is passed
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ var (
|
|||
rootCmd = &cobra.Command{
|
||||
Use: "ascii-image-converter [image paths/urls]",
|
||||
Short: "Converts images and gifs into ascii art",
|
||||
Version: "1.9.2",
|
||||
Version: "1.10.0",
|
||||
Long: "This tool converts images into ascii art and prints them on the terminal.\nFurther configuration can be managed with flags.",
|
||||
|
||||
// Not RunE since help text is getting larger and seeing it for every error impacts user experience
|
||||
|
|
@ -128,7 +128,7 @@ func init() {
|
|||
rootCmd.Flags().SortFlags = false
|
||||
|
||||
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.ascii-image-converter.yaml)")
|
||||
rootCmd.PersistentFlags().BoolVarP(&colored, "color", "C", false, "Display ascii art with original colors\nTerminal must support 24-bit colors\n(Inverts with --negative flag)\n(Overrides --grayscale and --font-color flags)\n")
|
||||
rootCmd.PersistentFlags().BoolVarP(&colored, "color", "C", false, "Display ascii art with original colors\nIf 24-bit colors aren't supported, uses 8-bit\n(Inverts with --negative flag)\n(Overrides --grayscale and --font-color flags)\n")
|
||||
rootCmd.PersistentFlags().BoolVar(&colorBg, "color-bg", false, "If some color flag is passed, use that color\non character background instead of foreground\n(Inverts with --negative flag)\n(Only applicable for terminal display)\n")
|
||||
rootCmd.PersistentFlags().IntSliceVarP(&dimensions, "dimensions", "d", nil, "Set width and height for ascii art in CHARACTER length\ne.g. -d 60,30 (defaults to terminal height)\n(Overrides --width and --height flags)\n")
|
||||
rootCmd.PersistentFlags().IntVarP(&width, "width", "W", 0, "Set width for ascii art in CHARACTER length\nHeight is kept to aspect ratio\ne.g. -W 60\n")
|
||||
|
|
|
|||
|
|
@ -16,12 +16,6 @@ limitations under the License.
|
|||
|
||||
package image_conversions
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gookit/color"
|
||||
)
|
||||
|
||||
var (
|
||||
// Reference taken from http://paulbourke.net/dataformats/asciiart/
|
||||
asciiTableSimple = " .:-=+*#%@"
|
||||
|
|
@ -55,7 +49,7 @@ 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, colorBg bool, customMap string, fontColor [3]int) [][]AsciiChar {
|
||||
func ConvertToAsciiChars(imgSet [][]AsciiPixel, negative, colored, grayscale, complex, colorBg bool, customMap string, fontColor [3]int) ([][]AsciiChar, error) {
|
||||
|
||||
height := len(imgSet)
|
||||
width := len(imgSet[0])
|
||||
|
|
@ -128,29 +122,33 @@ func ConvertToAsciiChars(imgSet [][]AsciiPixel, negative, colored, complex, colo
|
|||
tempInt = (len(chosenTable) - 1) - tempInt
|
||||
}
|
||||
|
||||
rStr := strconv.Itoa(r)
|
||||
gStr := strconv.Itoa(g)
|
||||
bStr := strconv.Itoa(b)
|
||||
|
||||
var char AsciiChar
|
||||
|
||||
char.Simple = chosenTable[tempInt]
|
||||
|
||||
var err error
|
||||
if colorBg {
|
||||
char.OriginalColor = color.Sprintf("<bg="+rStr+","+gStr+","+bStr+">%v</>", chosenTable[tempInt])
|
||||
char.OriginalColor, err = getColoredCharForTerm(uint8(r), uint8(g), uint8(b), chosenTable[tempInt], true)
|
||||
} else {
|
||||
char.OriginalColor = color.Sprintf("<fg="+rStr+","+gStr+","+bStr+">%v</>", chosenTable[tempInt])
|
||||
char.OriginalColor, err = getColoredCharForTerm(uint8(r), uint8(g), uint8(b), chosenTable[tempInt], false)
|
||||
}
|
||||
if (colored || grayscale) && err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If font color is not set, use a simple string. Otherwise, use True color
|
||||
if fontColor != [3]int{255, 255, 255} {
|
||||
fcR := strconv.Itoa(fontColor[0])
|
||||
fcG := strconv.Itoa(fontColor[1])
|
||||
fcB := strconv.Itoa(fontColor[2])
|
||||
fcR := fontColor[0]
|
||||
fcG := fontColor[1]
|
||||
fcB := fontColor[2]
|
||||
|
||||
if colorBg {
|
||||
char.SetColor = color.Sprintf("<bg="+fcR+","+fcG+","+fcB+">%v</>", chosenTable[tempInt])
|
||||
char.SetColor, err = getColoredCharForTerm(uint8(fcR), uint8(fcG), uint8(fcB), chosenTable[tempInt], true)
|
||||
} else {
|
||||
char.SetColor = color.Sprintf("<fg="+fcR+","+fcG+","+fcB+">%v</>", chosenTable[tempInt])
|
||||
char.SetColor, err = getColoredCharForTerm(uint8(fcR), uint8(fcG), uint8(fcB), chosenTable[tempInt], false)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +163,7 @@ func ConvertToAsciiChars(imgSet [][]AsciiPixel, negative, colored, complex, colo
|
|||
result = append(result, tempSlice)
|
||||
}
|
||||
|
||||
return result
|
||||
return result, nil
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -174,7 +172,7 @@ to a 2D image_conversions.AsciiChar slice
|
|||
|
||||
Unlike ConvertToAsciiChars(), this function calculates braille characters instead of ascii
|
||||
*/
|
||||
func ConvertToBrailleChars(imgSet [][]AsciiPixel, negative, colored, colorBg bool, fontColor [3]int, threshold int) [][]AsciiChar {
|
||||
func ConvertToBrailleChars(imgSet [][]AsciiPixel, negative, colored, grayscale, colorBg bool, fontColor [3]int, threshold int) ([][]AsciiChar, error) {
|
||||
|
||||
BrailleThreshold = uint32(threshold)
|
||||
|
||||
|
|
@ -216,29 +214,33 @@ func ConvertToBrailleChars(imgSet [][]AsciiPixel, negative, colored, colorBg boo
|
|||
}
|
||||
}
|
||||
|
||||
rStr := strconv.Itoa(r)
|
||||
gStr := strconv.Itoa(g)
|
||||
bStr := strconv.Itoa(b)
|
||||
|
||||
var char AsciiChar
|
||||
|
||||
char.Simple = brailleChar
|
||||
|
||||
var err error
|
||||
if colorBg {
|
||||
char.OriginalColor = color.Sprintf("<bg="+rStr+","+gStr+","+bStr+">%v</>", brailleChar)
|
||||
char.OriginalColor, err = getColoredCharForTerm(uint8(r), uint8(g), uint8(b), brailleChar, true)
|
||||
} else {
|
||||
char.OriginalColor = color.Sprintf("<fg="+rStr+","+gStr+","+bStr+">%v</>", brailleChar)
|
||||
char.OriginalColor, err = getColoredCharForTerm(uint8(r), uint8(g), uint8(b), brailleChar, false)
|
||||
}
|
||||
if (colored || grayscale) && err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If font color is not set, use a simple string. Otherwise, use True color
|
||||
if fontColor != [3]int{255, 255, 255} {
|
||||
fcR := strconv.Itoa(fontColor[0])
|
||||
fcG := strconv.Itoa(fontColor[1])
|
||||
fcB := strconv.Itoa(fontColor[2])
|
||||
fcR := fontColor[0]
|
||||
fcG := fontColor[1]
|
||||
fcB := fontColor[2]
|
||||
|
||||
if colorBg {
|
||||
char.SetColor = color.Sprintf("<bg="+fcR+","+fcG+","+fcB+">%v</>", brailleChar)
|
||||
char.SetColor, err = getColoredCharForTerm(uint8(fcR), uint8(fcG), uint8(fcB), brailleChar, true)
|
||||
} else {
|
||||
char.SetColor = color.Sprintf("<fg="+fcR+","+fcG+","+fcB+">%v</>", brailleChar)
|
||||
char.SetColor, err = getColoredCharForTerm(uint8(fcR), uint8(fcG), uint8(fcB), brailleChar, false)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -254,7 +256,7 @@ func ConvertToBrailleChars(imgSet [][]AsciiPixel, negative, colored, colorBg boo
|
|||
result = append(result, tempSlice)
|
||||
}
|
||||
|
||||
return result
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Iterate through the BrailleStruct table to see which dots need to be highlighted
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
"github.com/TheZoraiz/ascii-image-converter/aic_package/winsize"
|
||||
"github.com/disintegration/imaging"
|
||||
gookitColor "github.com/gookit/color"
|
||||
"github.com/makeworld-the-better-one/dither/v2"
|
||||
)
|
||||
|
||||
|
|
@ -200,3 +201,25 @@ func reverse(imgSet [][]AsciiPixel, flipX, flipY bool) [][]AsciiPixel {
|
|||
|
||||
return imgSet
|
||||
}
|
||||
|
||||
var termColorLevel string = gookitColor.TermColorLevel().String()
|
||||
|
||||
// This functions calculates terminal color level between rgb colors, 256-colors, 16-colors
|
||||
// and returns the character with escape codes appropriately
|
||||
func getColoredCharForTerm(r, g, b uint8, char string, background bool) (string, error) {
|
||||
var coloredChar string
|
||||
|
||||
if termColorLevel == "millions" {
|
||||
colorRenderer := gookitColor.RGB(uint8(r), uint8(g), uint8(b), background)
|
||||
coloredChar = colorRenderer.Sprintf("%v", char)
|
||||
|
||||
} else if termColorLevel == "hundreds" {
|
||||
colorRenderer := gookitColor.RGB(uint8(r), uint8(g), uint8(b), background).C256()
|
||||
coloredChar = colorRenderer.Sprintf("%v", char)
|
||||
|
||||
} else {
|
||||
return "", fmt.Errorf("your terminal supports neither 24-bit nor 8-bit colors. Other coloring options aren't available")
|
||||
}
|
||||
|
||||
return coloredChar, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
name: ascii-image-converter
|
||||
base: core18
|
||||
version: "1.9.2"
|
||||
version: "1.10.0"
|
||||
summary: Convert images and gifs into ascii art
|
||||
description: |
|
||||
ascii-image-converter is a command-line tool that converts images into ascii art and prints
|
||||
|
|
|
|||
Loading…
Reference in New Issue