mirror of
https://github.com/TheZoraiz/ascii-image-converter.git
synced 2026-05-17 00:45:58 +03:00
Set default image ratio to terminal height, included --map flag, improved help text
This commit is contained in:
@@ -28,7 +28,7 @@ archives:
|
||||
format: zip
|
||||
|
||||
files:
|
||||
- LICENSE
|
||||
- LICENSE.txt
|
||||
|
||||
replacements:
|
||||
linux: Linux
|
||||
|
||||
123
README.md
123
README.md
@@ -1,38 +1,36 @@
|
||||
|
||||
# ascii-image-converter
|
||||
|
||||
ascii-image-converter is a command-line tool that converts images into ascii art and prints them out onto the console. It is cross-platform so both Windows and Linux distributions are supported
|
||||
ascii-image-converter is a command-line tool that converts images into ascii art and prints them out onto the console. It is cross-platform so both Windows and Linux distributions are supported.
|
||||
|
||||
Image formats currently supported:
|
||||
* JPEG/JPG
|
||||
* PNG
|
||||
* WEBP
|
||||
* BMP
|
||||
* WEBP
|
||||
* TIFF/TIF
|
||||
|
||||
## Table of Contents
|
||||
- [Example](#example-source)
|
||||
- [Installation](#installation)
|
||||
* [Snap](#snap)
|
||||
* [Go](#go)
|
||||
* [Linux (binaries)](#linux)
|
||||
* [Windows (binaries)](#windows)
|
||||
- [Usage](#usage)
|
||||
* [Flags](#flags)
|
||||
- [Contributing](#contributing)
|
||||
- [Packages used](#packages-used)
|
||||
- [License](#license)
|
||||
|
||||
- [Example](#example-source)
|
||||
- [Installation](#installation)
|
||||
* [Snap](#snap)
|
||||
* [Go](#go)
|
||||
* [Linux (binaries)](#linux)
|
||||
* [Windows (binaries)](#windows)
|
||||
- [Usage](#usage)
|
||||
* [Flags](#flags)
|
||||
- [Contributing](#contributing)
|
||||
- [Packages used](#packages-used)
|
||||
- [License](#license)
|
||||
|
||||
### Example ([Source](https://medium.com/@sean.glancy/practical-applications-of-binary-trees-3097cf663062)):
|
||||
|
||||

|
||||
|
||||
### ASCII Art:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
### Snap
|
||||
@@ -40,12 +38,14 @@ Image formats currently supported:
|
||||
You can download through snap. However, the snap will not have access to hidden images and images outside the $HOME directory.
|
||||
|
||||
```
|
||||
sudo snap install ascii-image-converter --stable
|
||||
sudo snap install ascii-image-converter
|
||||
```
|
||||
Visit [the app's snap store listing](https://snapcraft.io/ascii-image-converter) for instructions regarding enabling snapd on your distribution.
|
||||
|
||||
<hr>
|
||||
|
||||
### Go
|
||||
|
||||
For installing through Go
|
||||
```
|
||||
go install github.com/TheZoraiz/ascii-image-converter@latest
|
||||
@@ -54,7 +54,8 @@ go install github.com/TheZoraiz/ascii-image-converter@latest
|
||||
For physically installing the binaries, follow the steps with respect to your OS.
|
||||
|
||||
### Linux
|
||||
Extract the archive for your chosen Linux architecture after downloading it from [here](https://github.com/TheZoraiz/ascii-image-converter/releases/latest), and open the extracted directory.
|
||||
|
||||
Download the archive for your distribution's architecture [here](https://github.com/TheZoraiz/ascii-image-converter/releases/latest), extract it, and open the extracted directory.
|
||||
|
||||
Now, open a terminal in the same directory and execute this command:
|
||||
|
||||
@@ -67,7 +68,7 @@ Now you can use ascii-image-converter in the terminal. Execute "ascii-image-conv
|
||||
|
||||
You will need to set an Environment Variable to the folder the ascii-image-converter.exe executable is placed in to be able to use it in the command prompt. Follow the instructions in case of confusion:
|
||||
|
||||
Extract the archive for the your chosen Windows architecture after downloading it from [here](https://github.com/TheZoraiz/ascii-image-converter/releases/latest). Open the newly created folder and copy the path to it from the top of the file explorer.
|
||||
Download the archive for your Windows architecture [here](https://github.com/TheZoraiz/ascii-image-converter/releases/latest), extract it, and open the extracted folder.
|
||||
* In Search, search for and then select: System (Control Panel)
|
||||
* Click the Advanced System settings link.
|
||||
* Click Environment Variables. In the section User Variables find the Path environment variable and select it. Click "Edit".
|
||||
@@ -82,77 +83,105 @@ Now, restart any open command prompt and execute "ascii-image-converter -h" for
|
||||
|
||||
Note: Decrease font size or increase terminal width (like zooming out) for maximum quality ascii art
|
||||
|
||||
To convert an image into ascii format, the usage is as follows:
|
||||
The basic usage for converting an image into ascii art is as follows. You can also supply paths to multiple images.
|
||||
|
||||
```
|
||||
ascii-image-converter [path to image]
|
||||
ascii-image-converter [image-paths]
|
||||
```
|
||||
Example
|
||||
Example:
|
||||
```
|
||||
ascii-image-converter myImage.jpeg
|
||||
```
|
||||
|
||||
### Flags
|
||||
|
||||
#### --complex OR -c
|
||||
Print the image with a wider array of ascii characters. Sometimes improves accuracy.
|
||||
#### --color OR -C
|
||||
|
||||
Display ascii art with the colors from original image. Works with the --negative flag as well.
|
||||
|
||||
```
|
||||
ascii-image-converter [path to image] -c
|
||||
ascii-image-converter [image-paths] -C
|
||||
# Or
|
||||
ascii-image-converter [path to image] --complex
|
||||
ascii-image-converter [image-paths] --color
|
||||
```
|
||||
|
||||
#### --complex OR -c
|
||||
|
||||
Print the image with a wider array of ascii characters for more detailed lighting density. Sometimes improves accuracy.
|
||||
```
|
||||
ascii-image-converter [image-paths] -c
|
||||
# Or
|
||||
ascii-image-converter [image-paths] --complex
|
||||
```
|
||||
|
||||
#### --dimensions OR -d
|
||||
Set the width and height for ascii art in CHARACTER lengths. (Don't immediately append another flag with -d)
|
||||
|
||||
Note: Don't immediately append another flag with -d
|
||||
Set the width and height for ascii art in CHARACTER lengths.
|
||||
```
|
||||
ascii-image-converter [path to image] -d <width>,<height>
|
||||
ascii-image-converter [image-paths] -d <width>,<height>
|
||||
# Or
|
||||
ascii-image-converter [path to image] --dimensions <width>,<height>
|
||||
ascii-image-converter [image-paths] --dimensions <width>,<height>
|
||||
```
|
||||
Example:
|
||||
```
|
||||
ascii-image-converter [path to image] -d 100,30
|
||||
ascii-image-converter [image-paths] -d 100,30
|
||||
```
|
||||
|
||||
#### --color OR -C
|
||||
Display ascii art with the colors from original image. Works with the -n flag as well.
|
||||
#### --map OR -m
|
||||
|
||||
Note: Don't immediately append another flag with -m
|
||||
Pass a string of your own ascii characters to map against. Passed characters must start from darkest character and end with lightest. There is no limit to number of characters.
|
||||
|
||||
Notes: Empty spaces can be passed if string is passed inside quotation marks. You can use both single or double quote for quotation marks. For repeating quotation mark inside string, append it with \ (such as \\").
|
||||
|
||||
```
|
||||
ascii-image-converter [path to image] -C
|
||||
ascii-image-converter [image-paths] -m "<string-of-characters>"
|
||||
# Or
|
||||
ascii-image-converter [path to image] --color
|
||||
ascii-image-converter [image-paths] --map "<string-of-characters>"
|
||||
```
|
||||
Following example contains 7 depths of lighting.
|
||||
```
|
||||
ascii-image-converter [image-paths] -m " .-=+#@"
|
||||
```
|
||||
|
||||
#### --negative OR -n
|
||||
Display ascii art in negative colors. Works with both uncolored and colored text from -C flag.
|
||||
|
||||
Display ascii art in negative colors. Works with both uncolored and colored text from --color flag.
|
||||
|
||||
```
|
||||
ascii-image-converter [path to image] -n
|
||||
ascii-image-converter [image-paths] -n
|
||||
# Or
|
||||
ascii-image-converter [path to image] --negative
|
||||
ascii-image-converter [image-paths] --negative
|
||||
```
|
||||
|
||||
#### --save OR -s
|
||||
Save the printed ascii art in a file ascii-image.txt in the directory passed alongside. (Don't immediately append another flag with -s)
|
||||
|
||||
Save ascii art in the format `<image-name>-<image-extension>-ascii-art.txt` in the directory path passed to the flag.
|
||||
|
||||
Example for current directory:
|
||||
|
||||
```
|
||||
ascii-image-converter [path to image] --save ./
|
||||
ascii-image-converter [image-paths] --save .
|
||||
# Or
|
||||
ascii-image-converter [path to image] -s ./
|
||||
ascii-image-converter [image-paths] -s .
|
||||
```
|
||||
|
||||
#### --formats OR -f
|
||||
|
||||
Display supported image formats.
|
||||
|
||||
```
|
||||
ascii-image-converter [path to image] --formats
|
||||
ascii-image-converter [image-paths] --formats
|
||||
# Or
|
||||
ascii-image-converter [path to image] -f
|
||||
ascii-image-converter [image-paths] -f
|
||||
```
|
||||
|
||||
<br>
|
||||
You can combine flags as well. Following command outputs colored and negative ascii art, with fixed 100 by 30 character dimensions, custom defined ascii characters " .-=+#@" and saves the output in current directory as well.
|
||||
|
||||
You can combine flags as well. Following command outputs colored and negative ascii art, with complex characters, fixed 100 by 30 character dimensions and saves the output in current directory as well.
|
||||
```
|
||||
ascii-image-converter [path to image] -Ccnd 100,30 -s ./
|
||||
ascii-image-converter [image-paths] -Cnd 100,30 -m " .-=+#@" -s ./
|
||||
```
|
||||
|
||||
<br>
|
||||
@@ -175,6 +204,6 @@ You can fork the project and implement any changes you want for a pull request.
|
||||
|
||||
[github.com/gookit/color](https://github.com/gookit/color)
|
||||
|
||||
|
||||
## License
|
||||
[Apache-2.0](https://github.com/TheZoraiz/ascii-image-converter/blob/master/LICENSE)
|
||||
|
||||
[Apache-2.0](https://github.com/TheZoraiz/ascii-image-converter/blob/master/LICENSE)
|
||||
63
cmd/root.go
63
cmd/root.go
@@ -49,15 +49,14 @@ var (
|
||||
negative bool
|
||||
formatsTrue bool
|
||||
colored bool
|
||||
customMap string
|
||||
|
||||
// Root commands
|
||||
rootCmd = &cobra.Command{
|
||||
Use: "ascii-image-converter [image path]",
|
||||
Use: "ascii-image-converter [image-paths]",
|
||||
Short: "Converts images into ascii format",
|
||||
Version: "1.2.3",
|
||||
Example: " ascii-image-converter myImage.jpeg\n\n" +
|
||||
"For further details, visit https://github.com/TheZoraiz/ascii-image-converter",
|
||||
Long: `This tool converts images into ascii format and prints them onto the terminal window. Further configuration can be managed with flags`,
|
||||
Version: "1.2.4",
|
||||
Long: "This tool converts images into ascii art and prints them on the terminal.\nFurther configuration can be managed with flags.",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
if formatsTrue {
|
||||
@@ -65,18 +64,26 @@ var (
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(args) != 1 {
|
||||
return fmt.Errorf("Requires 1 image path, got %v", len(args))
|
||||
}
|
||||
|
||||
numberOfDimensions := len(dimensions)
|
||||
if dimensions != nil && numberOfDimensions != 2 {
|
||||
return fmt.Errorf("-d requires 2 dimensions, got %v", numberOfDimensions)
|
||||
}
|
||||
|
||||
imagePath := args[0]
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("Need at least 1 image path")
|
||||
}
|
||||
|
||||
return convertImage(imagePath)
|
||||
if len(customMap) < 2 && customMap != "" {
|
||||
fmt.Println("Need at least 2 characters")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
for _, imagePath := range args {
|
||||
if err := convertImage(imagePath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
)
|
||||
@@ -93,22 +100,25 @@ func convertImage(imagePath string) error {
|
||||
|
||||
pic, err := os.Open(imagePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to open file: %w", err)
|
||||
fmt.Printf("Unable to open file: %v\n", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
defer pic.Close()
|
||||
|
||||
imData, _, err := image.Decode(pic)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to decode file: %w", err)
|
||||
fmt.Printf("Error decoding file: %v\n", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
imgSet, err := imgMani.ConvertToAsciiPixels(imData, dimensions)
|
||||
if err != nil {
|
||||
return err
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
var asciiSet [][]imgMani.AsciiChar
|
||||
asciiSet = imgMani.ConvertToAscii(imgSet, negative, colored, compl)
|
||||
asciiSet = imgMani.ConvertToAscii(imgSet, negative, colored, compl, customMap)
|
||||
|
||||
var ascii []string
|
||||
ascii = flattenAscii(asciiSet, colored)
|
||||
@@ -116,7 +126,8 @@ func convertImage(imagePath string) error {
|
||||
// Save art before printing it, if flag is passed
|
||||
if savePath != "" {
|
||||
if err := saveAsciiArt(asciiSet, imagePath); err != nil {
|
||||
return err
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +164,7 @@ func saveAsciiArt(asciiSet [][]imgMani.AsciiChar, imagePath string) error {
|
||||
if _, err := os.Stat(savePath); !os.IsNotExist(err) {
|
||||
return ioutil.WriteFile(savePath+saveFileName, []byte(strings.Join(saveAscii, "\n")), 0777)
|
||||
} else {
|
||||
return fmt.Errorf("Path does not exist.")
|
||||
return fmt.Errorf("Save path does not exist.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,13 +212,19 @@ func init() {
|
||||
cobra.OnInitialize(initConfig)
|
||||
|
||||
// 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 the colors from original image (Can work with the -n flag)")
|
||||
rootCmd.PersistentFlags().BoolVarP(&compl, "complex", "c", false, "Display ascii characters in a larger range, may result in higher quality")
|
||||
rootCmd.PersistentFlags().IntSliceVarP(&dimensions, "dimensions", "d", nil, "Set width and height for ascii art in CHARACTER length e.g. 100,30 (defaults to terminal size)")
|
||||
rootCmd.PersistentFlags().BoolVarP(&formatsTrue, "formats", "f", false, "Display supported image formats")
|
||||
rootCmd.PersistentFlags().BoolVarP(&negative, "negative", "n", false, "Display ascii art in negative colors (Can work with the -C flag)")
|
||||
rootCmd.PersistentFlags().StringVarP(&savePath, "save", "s", "", "Save ascii art in an <image-name>-<image-extension>-ascii-art.txt file in a given path (pass . for current directory)")
|
||||
rootCmd.PersistentFlags().BoolVarP(&colored, "color", "C", false, "Display ascii art with the colors from original image\n(Can work with the -n flag)\n")
|
||||
rootCmd.PersistentFlags().BoolVarP(&compl, "complex", "c", false, "Display ascii characters in a larger range\nMay result in higher quality\n")
|
||||
rootCmd.PersistentFlags().IntSliceVarP(&dimensions, "dimensions", "d", nil, "Set width and height for ascii art in CHARACTER length\ne.g. -d 100,30 (defaults to terminal height)\n")
|
||||
rootCmd.PersistentFlags().BoolVarP(&formatsTrue, "formats", "f", false, "Display supported image formats\n")
|
||||
rootCmd.PersistentFlags().StringVarP(&customMap, "map", "m", "", "Give custom ascii characters to map against\nOrdered from darkest to lightest\ne.g. -m \" .-+#@\" (Quotation marks excluded from map)\n(Cancels --complex flag)\n")
|
||||
rootCmd.PersistentFlags().BoolVarP(&negative, "negative", "n", false, "Display ascii art in negative colors\n(Can work with the --color flag)\n")
|
||||
rootCmd.PersistentFlags().StringVarP(&savePath, "save", "s", "", "Save ascii art in the format:\n<image-name>-<image-extension>-ascii-art.txt\nFile will be saved in passed path\n(pass . for current directory)\n")
|
||||
|
||||
defaultUsageTemplate := rootCmd.UsageTemplate()
|
||||
rootCmd.SetUsageTemplate("\nCopyright © 2021 Zoraiz Hassan <hzoraiz8@gmail.com>\n" +
|
||||
"Distributed under the Apache License Version 2.0 (Apache-2.0)\n" +
|
||||
"For further details, visit https://github.com/TheZoraiz/ascii-image-converter\n\n" +
|
||||
defaultUsageTemplate)
|
||||
}
|
||||
|
||||
// initConfig reads in config file and ENV variables if set.
|
||||
|
||||
@@ -123,16 +123,24 @@ type AsciiChar struct {
|
||||
//
|
||||
// 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.
|
||||
func ConvertToAscii(imgSet [][]AsciiPixel, negative bool, colored bool, complex bool) [][]AsciiChar {
|
||||
func ConvertToAscii(imgSet [][]AsciiPixel, negative bool, colored bool, complex bool, customMap string) [][]AsciiChar {
|
||||
|
||||
height := len(imgSet)
|
||||
width := len(imgSet[0])
|
||||
|
||||
var chosenTable map[int]string
|
||||
if complex {
|
||||
chosenTable = asciiTableDetailed
|
||||
|
||||
if customMap == "" {
|
||||
if complex {
|
||||
chosenTable = asciiTableDetailed
|
||||
} else {
|
||||
chosenTable = asciiTableSimple
|
||||
}
|
||||
} else {
|
||||
chosenTable = asciiTableSimple
|
||||
chosenTable = map[int]string{}
|
||||
for index, char := range customMap {
|
||||
chosenTable[index] = string(char)
|
||||
}
|
||||
}
|
||||
|
||||
result := make([][]AsciiChar, height)
|
||||
|
||||
@@ -38,31 +38,40 @@ type AsciiPixel struct {
|
||||
// ranges from 0 to 65535, while RGB values are separate.
|
||||
func ConvertToAsciiPixels(img image.Image, dimensions []int) ([][]AsciiPixel, error) {
|
||||
|
||||
var terminalWidth, terminalHeight int
|
||||
var asciiWidth, asciiHeight int
|
||||
|
||||
var smallImg image.Image
|
||||
|
||||
// Get dimensions of current terminal
|
||||
if len(dimensions) == 0 {
|
||||
|
||||
terminalWidth, _ = consolesize.GetConsoleSize()
|
||||
// Following code in this condition calculates ratio according to terminal height
|
||||
|
||||
// Sometimes full length outputs print empty lines between ascii art
|
||||
terminalWidth -= 1
|
||||
terminalWidth, terminalHeight := consolesize.GetConsoleSize()
|
||||
asciiHeight = terminalHeight - 1
|
||||
|
||||
// Passing 0 in place of height keeps the original image's aspect ratio
|
||||
smallImg = resize.Resize(uint(terminalWidth), 0, img, resize.Lanczos3)
|
||||
terminalHeight = smallImg.Bounds().Max.Y - smallImg.Bounds().Min.Y
|
||||
// Passing 0 in place of width keeps the original image's aspect ratio
|
||||
smallImg = resize.Resize(0, uint(asciiHeight), img, resize.Lanczos3)
|
||||
asciiWidth = smallImg.Bounds().Max.X - smallImg.Bounds().Min.X
|
||||
|
||||
// To fix height ratio in eventual ascii art
|
||||
terminalHeight = int(0.5 * float32(terminalHeight))
|
||||
// To fix aspect ratio in eventual ascii art
|
||||
asciiWidth = int(2 * float32(asciiWidth))
|
||||
|
||||
smallImg = resize.Resize(uint(terminalWidth), uint(terminalHeight), img, resize.Lanczos3)
|
||||
// If ascii width exceeds terminal width, change ratio with respect to terminal width
|
||||
if asciiWidth > terminalWidth {
|
||||
smallImg = resize.Resize(uint(terminalWidth), 0, img, resize.Lanczos3)
|
||||
asciiWidth = terminalWidth
|
||||
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)
|
||||
|
||||
} else {
|
||||
terminalWidth = dimensions[0]
|
||||
terminalHeight = dimensions[1]
|
||||
smallImg = resize.Resize(uint(terminalWidth), uint(terminalHeight), img, resize.Lanczos3)
|
||||
asciiWidth = dimensions[0]
|
||||
asciiHeight = dimensions[1]
|
||||
smallImg = resize.Resize(uint(asciiWidth), uint(asciiHeight), img, resize.Lanczos3)
|
||||
}
|
||||
|
||||
// If there are passed dimensions, check whether the width exceeds terminal width
|
||||
@@ -75,9 +84,9 @@ func ConvertToAsciiPixels(img image.Image, dimensions []int) ([][]AsciiPixel, er
|
||||
}
|
||||
|
||||
// Initialize imgSet 2D slice
|
||||
imgSet := make([][]AsciiPixel, terminalHeight)
|
||||
imgSet := make([][]AsciiPixel, asciiHeight)
|
||||
for i := range imgSet {
|
||||
imgSet[i] = make([]AsciiPixel, terminalWidth)
|
||||
imgSet[i] = make([]AsciiPixel, asciiWidth)
|
||||
}
|
||||
|
||||
b := smallImg.Bounds()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: ascii-image-converter
|
||||
base: core18
|
||||
version: "1.2.3"
|
||||
version: "1.2.4"
|
||||
summary: Converts images into ascii format
|
||||
description: |
|
||||
This tool converts images into ascii format and prints them onto the terminal window.
|
||||
|
||||
Reference in New Issue
Block a user