Added APT repo
This commit is contained in:
parent
a421952bfe
commit
ed3dfa1ed5
|
|
@ -13,11 +13,25 @@ builds:
|
||||||
- windows
|
- windows
|
||||||
|
|
||||||
goarch:
|
goarch:
|
||||||
|
# Architectures for executable binary generation
|
||||||
- amd64
|
- amd64
|
||||||
- arm64
|
- arm64
|
||||||
- arm
|
- arm
|
||||||
- 386
|
- 386
|
||||||
|
|
||||||
|
# Specifying all architectures for .deb and .rpm generation
|
||||||
|
# - 386
|
||||||
|
# - amd64
|
||||||
|
# - arm
|
||||||
|
# - arm64
|
||||||
|
# - ppc64
|
||||||
|
# - ppc64le
|
||||||
|
# - mips
|
||||||
|
# - mipsle
|
||||||
|
# - mips64
|
||||||
|
# - mips64le
|
||||||
|
|
||||||
|
|
||||||
archives:
|
archives:
|
||||||
-
|
-
|
||||||
name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
|
name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
|
||||||
|
|
@ -50,3 +64,25 @@ changelog:
|
||||||
exclude:
|
exclude:
|
||||||
- '^docs:'
|
- '^docs:'
|
||||||
- '^test:'
|
- '^test:'
|
||||||
|
|
||||||
|
nfpms:
|
||||||
|
-
|
||||||
|
package_name: ascii-image-converter
|
||||||
|
file_name_template: "{{ .ProjectName }}_{{ .Arch }}"
|
||||||
|
|
||||||
|
homepage: https://github.com/TheZoraiz/ascii-image-converter
|
||||||
|
vendor: Zoraiz Hassan
|
||||||
|
maintainer: Zoraiz Hassan <hzoraiz8@gmail.com>
|
||||||
|
description: Convert images into ascii art
|
||||||
|
license: Apache 2.0
|
||||||
|
|
||||||
|
formats:
|
||||||
|
- deb
|
||||||
|
- rpm
|
||||||
|
|
||||||
|
release: 1
|
||||||
|
section: graphics
|
||||||
|
priority: optional
|
||||||
|
|
||||||
|
rpm:
|
||||||
|
compression: lzma
|
||||||
|
|
|
||||||
38
README.md
38
README.md
|
|
@ -1,3 +1,5 @@
|
||||||
|
|
||||||
|
|
||||||
# ascii-image-converter
|
# ascii-image-converter
|
||||||
|
|
||||||
[](https://github.com/TheZoraiz/ascii-image-converter/releases/latest)
|
[](https://github.com/TheZoraiz/ascii-image-converter/releases/latest)
|
||||||
|
|
@ -21,6 +23,7 @@ Input formats currently supported:
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
- [Installation](#installation)
|
- [Installation](#installation)
|
||||||
|
* [Ubuntu / Ubuntu-based](#ubuntu-or-ubuntu-based-distros)
|
||||||
* [Snap](#snap)
|
* [Snap](#snap)
|
||||||
* [Go](#go)
|
* [Go](#go)
|
||||||
* [Linux (binaries)](#linux)
|
* [Linux (binaries)](#linux)
|
||||||
|
|
@ -34,11 +37,25 @@ Input formats currently supported:
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
### Ubuntu or Ubuntu-based Distros
|
||||||
|
|
||||||
|
Execute the following commands in order:
|
||||||
|
|
||||||
|
```
|
||||||
|
echo 'deb [trusted=yes] https://apt.fury.io/zoraiz/ /' | sudo tee -a /etc/apt/sources.list.d/fury.list
|
||||||
|
```
|
||||||
|
```
|
||||||
|
sudo apt update
|
||||||
|
```
|
||||||
|
```
|
||||||
|
sudo apt install -y ascii-image-converter
|
||||||
|
```
|
||||||
|
|
||||||
### Snap
|
### Snap
|
||||||
|
|
||||||
You can download through snap.
|
You can download through snap.
|
||||||
|
|
||||||
Note: The snap will not have access to hidden files and files outside the $HOME directory. This includes write access for the ascii art saving files as well.
|
Note: The snap will not have access to hidden images and images outside the $HOME directory. This includes write access for saving ascii images and text files as well.
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo snap install ascii-image-converter
|
sudo snap install ascii-image-converter
|
||||||
|
|
@ -68,20 +85,20 @@ Now, open a terminal in the same directory and execute this command:
|
||||||
```
|
```
|
||||||
sudo cp ascii-image-converter /usr/local/bin/
|
sudo cp ascii-image-converter /usr/local/bin/
|
||||||
```
|
```
|
||||||
Now you can use ascii-image-converter in the terminal. Execute `ascii-image-converter -h` for more details.
|
Now you can use ascii-image-converter in the terminal. Execute "ascii-image-converter -h" for more details.
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
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:
|
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:
|
||||||
|
|
||||||
Download the archive for your Windows architecture [here](https://github.com/TheZoraiz/ascii-image-converter/releases/latest), extract it, and open the extracted folder. Now, copy the folder path from the top of the file explorer and follow these instructions:
|
Download the archive for your Windows architecture [here](https://github.com/TheZoraiz/ascii-image-converter/releases/latest), extract it, and open the extracted folder. Now, copy the folder path from the top of the file explorer and follow these instructions:
|
||||||
* In Search, search for and then select "view advanced system settings" (Control Panel)
|
* In Search, search for and then select: System (Control Panel)
|
||||||
* Click `Environment Variables`.
|
* Click the Advanced System settings link.
|
||||||
* In the section `User Variables`, find the `Path` environment variable and select it. Click `Edit`.
|
* Click Environment Variables. In the section User Variables find the Path environment variable and select it. Click "Edit".
|
||||||
* In the Edit Environment Variable window, click `New` on the right side and then paste the path of the folder that you copied initially.
|
* In the Edit Environment Variable window, click "New" and then paste the path of the folder that you copied initially.
|
||||||
* Click `Ok` on all open windows.
|
* Click "Ok" on all open windows.
|
||||||
|
|
||||||
Now, restart any open command prompt and execute `ascii-image-converter -h` for more details.
|
Now, restart any open command prompt and execute "ascii-image-converter -h" for more details.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
@ -256,11 +273,6 @@ Note: This is an experimental feature and may not result in the finest quality G
|
||||||
|
|
||||||
Saves the passed GIF as an ascii art GIF with the name `<image-name>-ascii-art.gif` in the directory path passed to the flag.
|
Saves the passed GIF as an ascii art GIF with the name `<image-name>-ascii-art.gif` in the directory path passed to the flag.
|
||||||
|
|
||||||
Example for current directory:
|
|
||||||
```
|
|
||||||
ascii-image-converter [gif path/url] --save-gif .
|
|
||||||
```
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://raw.githubusercontent.com/TheZoraiz/ascii-image-converter/master/example_gifs/save.gif">
|
<img src="https://raw.githubusercontent.com/TheZoraiz/ascii-image-converter/master/example_gifs/save.gif">
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,252 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2021 Zoraiz Hassan <hzoraiz8@gmail.com>
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package aic_package
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"image"
|
||||||
|
"image/color/palette"
|
||||||
|
"image/draw"
|
||||||
|
"image/gif"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
imgManip "github.com/TheZoraiz/ascii-image-converter/image_manipulation"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GifFrame struct {
|
||||||
|
asciiCharSet [][]imgManip.AsciiChar
|
||||||
|
delay int
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This function grabs each image frame from passed gif and turns it into ascii art. If SaveGifPath flag is passed,
|
||||||
|
it'll turn each ascii art into an image instance of the same dimensions as the original gif and save them
|
||||||
|
as an ascii art gif.
|
||||||
|
|
||||||
|
Multi-threading has been implemented in multiple places due to long execution time
|
||||||
|
*/
|
||||||
|
func pathIsGif(gifPath, urlImgName string, pathIsURl bool, urlImgBytes []byte, localGif *os.File) (string, error) {
|
||||||
|
|
||||||
|
var (
|
||||||
|
originalGif *gif.GIF
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
if pathIsURl {
|
||||||
|
originalGif, err = gif.DecodeAll(bytes.NewReader(urlImgBytes))
|
||||||
|
} else {
|
||||||
|
originalGif, err = gif.DecodeAll(localGif)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("can't decode %v: %v", gifPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
asciiArtSet = make([]string, len(originalGif.Image))
|
||||||
|
gifFramesSlice = make([]GifFrame, len(originalGif.Image))
|
||||||
|
|
||||||
|
counter = 0
|
||||||
|
concurrentProcesses = 0
|
||||||
|
wg sync.WaitGroup
|
||||||
|
hostCpuCount = runtime.NumCPU()
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Printf("Generating ascii art... 0%%\r")
|
||||||
|
|
||||||
|
// Get first frame of gif and its dimensions
|
||||||
|
firstGifFrame := originalGif.Image[0].SubImage(originalGif.Image[0].Rect)
|
||||||
|
firstGifFrameWidth := firstGifFrame.Bounds().Dx()
|
||||||
|
firstGifFrameHeight := firstGifFrame.Bounds().Dy()
|
||||||
|
|
||||||
|
// Multi-threaded loop to decrease execution time
|
||||||
|
for i, frame := range originalGif.Image {
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
concurrentProcesses++
|
||||||
|
|
||||||
|
go func(i int, frame *image.Paletted) {
|
||||||
|
|
||||||
|
frameImage := frame.SubImage(frame.Rect)
|
||||||
|
|
||||||
|
// 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")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
var imgSet [][]imgManip.AsciiPixel
|
||||||
|
|
||||||
|
imgSet, err = imgManip.ConvertToAsciiPixels(frameImage, dimensions, flipX, flipY, full)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
asciiCharSet := imgManip.ConvertToAscii(imgSet, negative, colored, complex, customMap)
|
||||||
|
gifFramesSlice[i].asciiCharSet = asciiCharSet
|
||||||
|
gifFramesSlice[i].delay = originalGif.Delay[i]
|
||||||
|
|
||||||
|
ascii := flattenAscii(asciiCharSet, colored)
|
||||||
|
|
||||||
|
asciiArtSet[i] = strings.Join(ascii, "\n")
|
||||||
|
|
||||||
|
counter++
|
||||||
|
percentage := int((float64(counter) / float64(len(originalGif.Image))) * 100)
|
||||||
|
fmt.Printf("Generating ascii art... " + strconv.Itoa(percentage) + "%%\r")
|
||||||
|
|
||||||
|
wg.Done()
|
||||||
|
|
||||||
|
}(i, frame)
|
||||||
|
|
||||||
|
// Limit concurrent processes according to host's CPU count to avoid overwhelming memory
|
||||||
|
if concurrentProcesses == hostCpuCount {
|
||||||
|
wg.Wait()
|
||||||
|
concurrentProcesses = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
fmt.Printf(" \r")
|
||||||
|
|
||||||
|
// Save ascii art as .gif file before displaying it, if --save-gif flag is passed
|
||||||
|
if saveGifPath != "" {
|
||||||
|
|
||||||
|
// Storing save path string before executing ascii art to gif conversion
|
||||||
|
// This is done to avoid wasting time for invalid path errors
|
||||||
|
|
||||||
|
saveFileName, err := createSaveFileName(gifPath, urlImgName, "-ascii-art.gif")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
fullPathName, err := getFullSavePath(saveFileName, saveGifPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("can't save file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initializing some constants for gif. Done outside loop to save execution
|
||||||
|
outGif := &gif.GIF{
|
||||||
|
LoopCount: originalGif.LoopCount,
|
||||||
|
}
|
||||||
|
opts := gif.Options{
|
||||||
|
NumColors: 256,
|
||||||
|
Drawer: draw.FloydSteinberg,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initializing slices for each ascii art image as well as delay
|
||||||
|
var (
|
||||||
|
palettedImageSlice = make([]*image.Paletted, len(gifFramesSlice))
|
||||||
|
delaySlice = make([]int, len(gifFramesSlice))
|
||||||
|
)
|
||||||
|
|
||||||
|
// For the purpose of displaying counter and limiting concurrent processes
|
||||||
|
counter = 0
|
||||||
|
concurrentProcesses = 0
|
||||||
|
|
||||||
|
fmt.Printf("Saving gif... 0%%\r")
|
||||||
|
|
||||||
|
// Multi-threaded loop to decrease execution time
|
||||||
|
for i, gifFrame := range gifFramesSlice {
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
concurrentProcesses++
|
||||||
|
|
||||||
|
go func(i int, gifFrame GifFrame) {
|
||||||
|
|
||||||
|
img := originalGif.Image[i].SubImage(originalGif.Image[i].Rect)
|
||||||
|
|
||||||
|
tempImg, err := createGifFrameToSave(
|
||||||
|
gifFrame.asciiCharSet,
|
||||||
|
img,
|
||||||
|
colored,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Following code takes tempImg as image.Image instance and converts it into *image.Paletted instance
|
||||||
|
b := tempImg.Bounds()
|
||||||
|
|
||||||
|
palettedImg := image.NewPaletted(b, palette.Plan9[:opts.NumColors])
|
||||||
|
|
||||||
|
opts.Drawer.Draw(palettedImg, b, tempImg, image.Point{})
|
||||||
|
|
||||||
|
palettedImageSlice[i] = palettedImg
|
||||||
|
delaySlice[i] = gifFrame.delay
|
||||||
|
|
||||||
|
counter++
|
||||||
|
percentage := int((float64(counter) / float64(len(gifFramesSlice))) * 100)
|
||||||
|
fmt.Printf("Saving gif... " + strconv.Itoa(percentage) + "%%\r")
|
||||||
|
|
||||||
|
wg.Done()
|
||||||
|
|
||||||
|
}(i, gifFrame)
|
||||||
|
|
||||||
|
// Limit concurrent processes according to host's CPU count to avoid overwhelming memory
|
||||||
|
if concurrentProcesses == hostCpuCount {
|
||||||
|
wg.Wait()
|
||||||
|
concurrentProcesses = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
outGif.Image = palettedImageSlice
|
||||||
|
outGif.Delay = delaySlice
|
||||||
|
|
||||||
|
gifFile, err := os.OpenFile(fullPathName, os.O_WRONLY|os.O_CREATE, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("can't save file: %v", err)
|
||||||
|
}
|
||||||
|
defer gifFile.Close()
|
||||||
|
|
||||||
|
gif.EncodeAll(gifFile, outGif)
|
||||||
|
|
||||||
|
fmt.Printf(" \r")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display the gif
|
||||||
|
loopCount := 0
|
||||||
|
for {
|
||||||
|
for i, asciiFrame := range asciiArtSet {
|
||||||
|
clearScreen()
|
||||||
|
fmt.Println(asciiFrame)
|
||||||
|
time.Sleep(time.Duration((time.Second * time.Duration(originalGif.Delay[i])) / 100))
|
||||||
|
}
|
||||||
|
|
||||||
|
// If gif is infinite loop
|
||||||
|
if originalGif.LoopCount == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
loopCount++
|
||||||
|
if loopCount == originalGif.LoopCount {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2021 Zoraiz Hassan <hzoraiz8@gmail.com>
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package aic_package
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
|
||||||
|
_ "embed"
|
||||||
|
|
||||||
|
imgManip "github.com/TheZoraiz/ascii-image-converter/image_manipulation"
|
||||||
|
"github.com/golang/freetype/truetype"
|
||||||
|
|
||||||
|
"github.com/fogleman/gg"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Unlike createImageToSave(), this function is optimized to maintain original image dimensions and shrink ascii
|
||||||
|
art font size to match it. This allows for greater execution speed, which is necessary since a gif contains
|
||||||
|
multiple images that need to be converted to ascii art, and the potential loss of ascii art quality (since
|
||||||
|
large ascii art instances will shrink the font too much).
|
||||||
|
|
||||||
|
Furthermore, maintaining original gif's width and height also allows for gifs of smaller size.
|
||||||
|
*/
|
||||||
|
func createGifFrameToSave(asciiArt [][]imgManip.AsciiChar, img image.Image, colored bool) (image.Image, error) {
|
||||||
|
|
||||||
|
// Original image dimensions
|
||||||
|
x := img.Bounds().Dx()
|
||||||
|
y := img.Bounds().Dy()
|
||||||
|
|
||||||
|
// Ascii art dimensions
|
||||||
|
asciiWidth := len(asciiArt[0])
|
||||||
|
asciiHeight := len(asciiArt)
|
||||||
|
|
||||||
|
// Iterators to move pointer on the image to be made
|
||||||
|
var xIter float64
|
||||||
|
var yIter float64
|
||||||
|
|
||||||
|
var fontSize float64
|
||||||
|
|
||||||
|
// Conditions to alter resulting ascii gif dimensions according to ascii art dimensions
|
||||||
|
if asciiWidth > asciiHeight*2 {
|
||||||
|
yIter = float64(y) / float64(asciiHeight)
|
||||||
|
|
||||||
|
xIter = yIter / 2
|
||||||
|
x = int(xIter * float64(asciiWidth))
|
||||||
|
|
||||||
|
fontSize = xIter
|
||||||
|
|
||||||
|
} else {
|
||||||
|
xIter = float64(x) / float64(asciiWidth)
|
||||||
|
|
||||||
|
yIter = xIter * 2
|
||||||
|
y = int(yIter * float64(asciiHeight))
|
||||||
|
|
||||||
|
fontSize = xIter
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10 extra pixels on both x and y-axis to have 5 pixels of padding on each side
|
||||||
|
x += 10
|
||||||
|
y += 10
|
||||||
|
|
||||||
|
tempImg := image.NewRGBA(image.Rect(0, 0, x, y))
|
||||||
|
|
||||||
|
dc := gg.NewContext(x, y)
|
||||||
|
|
||||||
|
// Set image background as black
|
||||||
|
dc.SetRGB(0, 0, 0)
|
||||||
|
dc.Clear()
|
||||||
|
|
||||||
|
dc.DrawImage(tempImg, 0, 0)
|
||||||
|
|
||||||
|
// Load embedded font
|
||||||
|
tempFont, err := truetype.Parse(embeddedFontFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Font size increased during assignment to become more visible. This will not affect image drawing
|
||||||
|
robotoBoldFontFace := truetype.NewFace(tempFont, &truetype.Options{Size: fontSize * 1.5})
|
||||||
|
|
||||||
|
dc.SetFontFace(robotoBoldFontFace)
|
||||||
|
|
||||||
|
// Font color of text on picture is white by default
|
||||||
|
dc.SetColor(color.White)
|
||||||
|
|
||||||
|
// Pointer to track y-axis on the image frame
|
||||||
|
yImgPointer := 5.0
|
||||||
|
|
||||||
|
// These nested loops print each character in asciArt 2D slice separately
|
||||||
|
// so that their RGB colors can be maintained in the resulting image
|
||||||
|
for _, line := range asciiArt {
|
||||||
|
|
||||||
|
// Pointer to track x-axis on the image frame
|
||||||
|
xImgPointer := 5.0
|
||||||
|
|
||||||
|
for _, char := range line {
|
||||||
|
|
||||||
|
r := uint8(char.RgbValue[0])
|
||||||
|
g := uint8(char.RgbValue[1])
|
||||||
|
b := uint8(char.RgbValue[2])
|
||||||
|
|
||||||
|
if colored {
|
||||||
|
// Simple put, dc.SetColor() sets color for EACH character before printing it
|
||||||
|
dc.SetColor(color.RGBA{r, g, b, 255})
|
||||||
|
}
|
||||||
|
|
||||||
|
dc.DrawStringWrapped(char.Simple, xImgPointer, yImgPointer, 0, 0, float64(x), 1.8, gg.AlignLeft)
|
||||||
|
|
||||||
|
// Incremet x-axis pointer character so new one can be printed after it
|
||||||
|
// Set to the same constant as in line
|
||||||
|
xImgPointer += xIter
|
||||||
|
}
|
||||||
|
|
||||||
|
dc.DrawStringWrapped("\n", xImgPointer, yImgPointer, 0, 0, float64(x), 1.8, gg.AlignLeft)
|
||||||
|
|
||||||
|
// Incremet pointer for y axis after every line printed, so
|
||||||
|
// new line can start at below the previous one on next iteration
|
||||||
|
yImgPointer += yIter
|
||||||
|
}
|
||||||
|
|
||||||
|
return dc.Image(), nil
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue