├── .github
└── workflows
│ ├── build.yml
│ └── release.yml
├── .gitignore
├── .idea
├── .gitignore
├── dye.iml
├── libraries
│ └── dye_linux.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── README.rst
├── dye
├── dye-linux.zip
├── dye.nimble
├── ex
├── LakesideVillage.jpg
├── conv-LakesideVillage.png
├── conv-unknown.png
└── unknown.png
├── lib
├── args.nim
├── colors.nim
├── palettes.nim
└── updates.nim
├── scripts
└── zigcc
└── src
└── dye.nim
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | - push
5 | - pull_request
6 |
7 | jobs:
8 | build:
9 | name: ${{ matrix.os }}
10 | runs-on: ${{ matrix.os }}
11 | strategy:
12 | matrix:
13 | os:
14 | - ubuntu-latest
15 | - macOS-latest
16 | - windows-latest
17 |
18 | steps:
19 | - name: Checkout sources
20 | uses: actions/checkout@v2
21 | - uses: alaviss/setup-nim@0.1.1
22 | with:
23 | path: 'nim'
24 | version: devel
25 | - uses: actions/cache@v3.1.0-beta.1
26 | with:
27 | path: |
28 | ../../../../.nimble/pkgs/
29 | key: ${{ runner.os }}-nim-${{ hashFiles('**/nimble.lock') }}
30 | - name: Install dependacies
31 | if: steps.cache.outputs.cache-hit != 'false'
32 | run: nimble install -d -y --deepcopy:on
33 | - name: Build
34 | run: nimble build -d:release -d:ssl --verbose
35 | - name: Cache
36 | - uses: actions/upload-artifact@v2
37 | if: ${{ matrix.os != 'windows-latest' }}
38 | with:
39 | name: dye-${{ matrix.os }}
40 | path: dye
41 | - uses: actions/upload-artifact@v2
42 | if: ${{ matrix.os == 'windows-latest' }}
43 | with:
44 | name: dye-${{ matrix.os }}
45 | path: dye.exe
46 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | workflow_dispatch:
5 | release:
6 | types: [released]
7 |
8 | jobs:
9 | build:
10 | name: ${{ matrix.os }}
11 | runs-on: ${{ matrix.os }}
12 | strategy:
13 | matrix:
14 | os:
15 | - ubuntu-latest
16 | #- windows-latest
17 | permissions:
18 | contents: write
19 | checks: write
20 |
21 | actions: read
22 | issues: read
23 | packages: write
24 | pull-requests: read
25 | repository-projects: read
26 | statuses: read
27 |
28 | steps:
29 | - name: Checkout sources
30 | uses: actions/checkout@v2
31 | - uses: iffy/install-nim@v4
32 | with:
33 | version: binary:stable
34 | - name: Build
35 | run: |
36 | nimble install -d -y
37 | nimble build -d:release --deepcopy:on
38 | - uses: thedoctor0/zip-release@main
39 | if: ${{ matrix.os == 'ubuntu-latest' }}
40 | with:
41 | type: 'zip'
42 | filename: dye-linux.zip
43 | path: dye
44 | - uses: thedoctor0/zip-release@main
45 | if: ${{ matrix.os == 'windows-latest' }}
46 | with:
47 | type: 'zip'
48 | filename: dye-windows.zip
49 | path: dye.exe
50 |
51 | - name: Release
52 | uses: alexellis/upload-assets@0.4.0
53 | env:
54 | GITHUB_TOKEN: ${{ secrets.github_token }}
55 | with:
56 | asset_paths: '["dye-*.zip"]'
57 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/dye.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/libraries/dye_linux.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | dye
2 | ===
3 |
4 | An ultrafast image colorizer tool
5 | ---------------------------------
6 |
7 | Installation
8 | ~~~~~~~~~~~~
9 |
10 | From Source
11 | ^^^^^^^^^^^
12 |
13 | **Dependencies Required:**
14 | * nim
15 | * nimble
16 |
17 | .. code:: bash
18 |
19 | nimble install dye@"#head"
20 |
21 | Binary
22 | ^^^^^^
23 |
24 | There are many binaries for different operating systems and
25 | architectures on the github releases page
26 |
27 |
28 | Packages
29 | ^^^^^^^^
30 | .. raw:: html
31 |
32 |
37 | Currently dye can be installed from
38 | * AUR
39 | * Nimble
40 | * Jitter
41 | You can install from `jitter `_ with the command: ``jitter install gh:Infinitybeond1/dye``
42 |
43 | Usage
44 | ~~~~~
45 |
46 | .. code-block:: bash
47 |
48 | # Get command info
49 | dye --help
50 |
51 | # Convert 'test.jpg' using the dark-decay color palette (available color palettes: decay, darkdecay, decayce, articblush, catppuccin, ok, nord, everforest, iceberg)
52 | dye -b -p dark-decay test.jpg
53 |
54 | # Convert the image to black and white
55 | dye -b -p "#000000,#FFFFFF" test.jpg
56 |
57 | # List color palettes
58 | dye list
59 |
60 | Contributing
61 | ~~~~~~~~~~~~
62 |
63 | Feel free to open a pull request if you wish to make any changes, here
64 | are a few of the ways you can help
65 | * Create some color palettes (lib/palettes.nim) they are just exported sequences of quoted hex codes
66 | * Help me improve the docs
67 | * Package it for platforms
68 |
--------------------------------------------------------------------------------
/dye:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arashi-software/dye/78c7e2bca3438feb5cb025d12fb59e28443051e4/dye
--------------------------------------------------------------------------------
/dye-linux.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arashi-software/dye/78c7e2bca3438feb5cb025d12fb59e28443051e4/dye-linux.zip
--------------------------------------------------------------------------------
/dye.nimble:
--------------------------------------------------------------------------------
1 | version = "1.2.1"
2 | author = "Luke"
3 | description = "An image colorizer"
4 | license = "GPL-3.0-or-later"
5 | srcDir = "src"
6 | bin = @["dye"]
7 |
8 | requires "nim >= 1.4.8"
9 | requires "progress"
10 | requires "pixie#head"
11 | requires "chroma#head"
12 | requires "therapist"
13 | requires "puppy"
14 | requires "zippy"
15 | #requires "downit"
16 |
17 | task lint, "Lint all *.nim files":
18 | exec "nimpretty --indent:2 */**.nim"
19 |
20 | task b, "Build for release":
21 | exec "nimble install -d:release && nim c --passL:'-s' -d:ssl -d:release src/dye && mkdir -p bin && mv -f src/dye bin/"
22 |
23 | task bi, "Build and install to your path (/usr/bin/)":
24 | exec "nimble install -d:release && nim c --passL:'-s' -d:release -d:ssl src/dye"
25 |
26 | task bz, "Build using zig as a c compiler":
27 | exec "nimble install -y -d && nim c -d:release -d:ssl --passL:'-s' --cc:clang --clang.exe:'scripts/zigcc' src/dye.nim && mkdir -p bin && mv -f src/dye bin/"
28 |
29 | task i, "Install a built version of dye":
30 | exec "sudo mv -fv bin/dye /usr/bin/"
31 |
32 | task bzi, "Build with zig and install":
33 | exec "nimble bz && nimble i"
34 |
--------------------------------------------------------------------------------
/ex/LakesideVillage.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arashi-software/dye/78c7e2bca3438feb5cb025d12fb59e28443051e4/ex/LakesideVillage.jpg
--------------------------------------------------------------------------------
/ex/conv-LakesideVillage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arashi-software/dye/78c7e2bca3438feb5cb025d12fb59e28443051e4/ex/conv-LakesideVillage.png
--------------------------------------------------------------------------------
/ex/conv-unknown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arashi-software/dye/78c7e2bca3438feb5cb025d12fb59e28443051e4/ex/conv-unknown.png
--------------------------------------------------------------------------------
/ex/unknown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arashi-software/dye/78c7e2bca3438feb5cb025d12fb59e28443051e4/ex/unknown.png
--------------------------------------------------------------------------------
/lib/args.nim:
--------------------------------------------------------------------------------
1 | import os, strutils, strformat, therapist
2 |
3 | const versionNum* = staticRead(fmt"../dye.nimble").splitLines()[0].split("=")[
4 | 1].strip().replace("\"", "")
5 |
6 | const release = defined(release)
7 |
8 | var bType: string
9 |
10 | if release:
11 | bType = "release"
12 | else:
13 | bType = "debug"
14 |
15 | let list = (
16 | help: newHelpArg()
17 | )
18 |
19 | let flip = (
20 | help: newHelpArg(),
21 | bar: newCountArg(@["--bar", "-b"], multi = false,
22 | help = "Show a progress bar"),
23 | output: newStringArg(@["--output", "-o"], help = "The file to write to",
24 | optional = true, defaultVal = "null"),
25 | file: newPathArg(@[""], help = "The file (or folder of files) to convert")
26 | )
27 |
28 | let luma = (
29 | help: newHelpArg(),
30 | bar: newCountArg(@["--bar", "-b"], multi = false,
31 | help = "Show a progress bar"),
32 | output: newStringArg(@["--output", "-o"], help = "The file to write to",
33 | optional = true, defaultVal = "null"),
34 | file: newPathArg(@[""], help = "The file (or folder of files) to convert")
35 | )
36 |
37 | let update = (
38 | help: newHelpArg()
39 | )
40 |
41 | let args* = (
42 | list: newCommandArg(@["list", "ls"], list, help = "List all palettes"),
43 | luma: newCommandArg(@["luma", "l"], luma,
44 | help = "Invert the luminance of an image"),
45 | flip: newCommandArg(@["flip", "f"], flip,
46 | help = "Flip the colors of an image"),
47 | update: newCommandArg(@["update", "u"], update, help = "Update dye"),
48 | bar: newCountArg(@["--bar", "-b"], multi = false,
49 | help = "Show a progress bar"),
50 | recursive: newCountArg(@["--rec", "-r"], multi = false,
51 | help = "Recursively scan directories"),
52 | output: newStringArg(@["--output", "-o"], help = "The file to write to",
53 | optional = true, defaultVal = "null"),
54 | file: newPathArg(@[""], help = "The file (or folder of files) to convert",
55 | optional = true),
56 | palette: newStringArg(@["--palette", "-p"], help = "The palette to use"),
57 | version: newCountArg(@["--version", "-v"], multi = false,
58 | help = "Show dye version information"),
59 | help: newHelpArg()
60 | )
61 |
62 | args.parseOrQuit(prolog = "Dye. The ultrafast image colorizer", command = "dye")
63 |
64 | if args.version.seen:
65 | echo "dye v$#\nrelease: $#" % @[versionNum, $release]
66 | quit(0)
67 |
68 | export therapist
69 |
--------------------------------------------------------------------------------
/lib/colors.nim:
--------------------------------------------------------------------------------
1 | import chroma,
2 | strutils,
3 | os,
4 | math,
5 | pixie,
6 | terminal,
7 | parseutils
8 |
9 | #proc parseColor(colors: seq[string]): seq[Color] =
10 | # var res: seq[Color] = @[]
11 | # for color in colors:
12 | # res.add(parseHex(color))
13 | # res
14 | #
15 | # proc prepareClosestColor*(colors: seq[string]): seq[ColorLAB] =
16 | # for color in colors:
17 | # result.add parseHex(color).to(ColorLAB)
18 | #
19 | # proc getClosestColor*(colors: seq[ColorLAB], old: Color): Color =
20 | # var
21 | # minDiff = 255
22 | # minDiffColor: ColorLAB
23 | # oldLab = old.to(ColorLab)
24 | # for color in colors:
25 | # let diff = oldLab.distance(color).int
26 | # if minDiff > diff:
27 | # minDiff = diff
28 | # minDiffColor = color
29 | # minDiffColor.to(Color)
30 |
31 | # Mimic the go function
32 | proc getClosestColor*(colors: seq[ColorRGB], old: Color): Color =
33 | var
34 | r: int
35 | g: int
36 | b: int
37 | r2: int
38 | g2: int
39 | b2: int
40 | oldcol: ColorRGB
41 | res: Color
42 | minDiff: float64 = 999.0 ^ 2
43 | distance: float64
44 | for color in colors:
45 | r = color.r.int()
46 | g = color.g.int()
47 | b = color.b.int()
48 | oldcol = old.to(ColorRGB)
49 | r2 = oldcol.r.int()
50 | g2 = oldcol.g.int()
51 | b2 = oldcol.b.int()
52 | distance = ((r2 - r)^2 + (g2 - g)^2 + (b2 - b)^2).float64
53 | if minDiff > distance:
54 | minDiff = distance
55 | res = color.to(Color)
56 | res
57 |
58 | proc prepareClosestColor*(colors: seq[string]): seq[ColorRGB] =
59 | var res: seq[ColorRGB] = @[]
60 | for color in colors:
61 | res.add(parseHex(color).to(ColorRGB))
62 | res
63 |
64 | proc getFilename*(file: string): string =
65 | extractFilename(file).split(".")[0]
66 |
67 | proc invertLuma*(color: Color): Color =
68 | var hsl = color.hsl()
69 | hsl.l = 100 - hsl.l
70 | result = color(hsl)
71 |
72 | proc checkFileOrDir*(file: string): seq[string] =
73 | if dirExists(file):
74 | result = @[]
75 | for lfile in walkDirRec(file):
76 | if ".png" in $lfile or ".jpg" in $lfile or ".jpeg" in $lfile:
77 | result.add(strip(lfile))
78 | else:
79 | if not fileExists(file):
80 | stdout.styledWriteLine(fgRed, "Error: ", fgWhite, "File not found: " &
81 | file & "\n")
82 | result = @[file]
83 |
84 | proc rmTag*(colors: seq[string]): seq[string] =
85 | for color in colors:
86 | if "#" in color:
87 | result.add(color.replace("#", ""))
88 | else:
89 | result.add(color)
90 |
91 | proc parseColors*(input: string): seq[string] = # Please return colours
92 | var
93 | i = 0
94 | buff = ""
95 | while i < input.len:
96 | i += input.skipWhile({'#', ' ', ','}, i)
97 | i += input.parseUntil(buff, ',', i)
98 | result.add buff
99 |
100 | proc save*(image: Image, path: string) =
101 | removeFile(path)
102 | image.writeFile(path)
103 |
--------------------------------------------------------------------------------
/lib/palettes.nim:
--------------------------------------------------------------------------------
1 | let pal* = (
2 | decay: @["#171B20", "#15191d", "#1a1e23", "#21262e", "#b6beca", "#e9a180",
3 | "#1a1e24", "#4d5768", "#b6beca", "#242931", "#e05f65", "#73c291",
4 | "#f1cf8a", "#70a5eb", "#c68aee", "#74bee9", "#b6beca", "#485263",
5 | "#e05f65", "#7ddac5", "#f1cf8a", "#70a5eb", "#c68aee", "#74bee9",
6 | "#b6beca"],
7 | darkdecay: @["#101419", "#0e1217", "#13171c", "#1a1e23", "#b6beca", "#15191e",
8 | "#e9a180", "#4d5768", "#b6beca", "#242931", "#e05f65", "#73c291",
9 | "#f1cf8a", "#70a5eb", "#c68aee", "#74bee9", "#b6beca", "#485263",
10 | "#e05f65", "#7ddac5", "#f1cf8a", "#70a5eb", "#c68aee", "#74bee9",
11 | "#b6beca"],
12 | decayce: @["#0d0f18", "#0b0d16", "#0f111a", "#11131c", "#a5b6cf", "#151720",
13 | "#ecd3a0", "#1c1e27", "#a5b6cf", "#151720", "#dd6777", "#90ceaa",
14 | "#f1d8a5", "#86aaec", "#c296eb", "#93cee9", "#a5b6cf", "#1c1e27",
15 | "#dd6777", "#90ceaa", "#ecd3a0", "#86aaec", "#c296eb", "#93cee9",
16 | "#cbced3"],
17 | articblush: @["#040c16", "#cce9ea", "#c2cae2", "#d9d7d6", "#323949",
18 | "#E6676B", "#A2E4B8", "#e2d06a", "#92bbed", "#ecc6e8", "#80ffff",
19 | "#cfebec", "#3d3e51", "#FF7377", "#AAF0C1", "#eadd94", "#bdd6f4",
20 | "#f9ecf7", "#b3ffff", "#edf7f8"],
21 | iceberg: @["#161821", "#1e2132", "#c6c8d1", "#d2d4de", "#6b7089",
22 | "#e27878", "#e98989", "#b4be82", "#c0ca8e",
23 | "#e2a478", "#e9b189",
24 | "#84a0c6", "#95c4ce", "#89b8c2", "#91acd1",
25 | "#a093c7", "#ada0d3"],
26 | catppuccin: @["#F5E0DC", "#F2CDCD", "#F5C2E7", "#CBA6F7", "#F38BA8",
27 | "#EBA0AC", "#FAB387", "#F9E2AF", "#A6E3A1", "#94E2D5", "#89DCEB",
28 | "#90C1FB",
29 | "#74C7EC", "#B4BEFE", "#C6D0F5", "#AEB7D9", "#969DBC", "#7E84A0",
30 | "#666A83", "#4E5167", "#36374A", "#1E1E2E", "#12121C", "#07070A"],
31 | ok: @["#0b0d10", "#0b0d10", "#d2daf4", "#d2daf4", "#636c7e", "#c44949",
32 | "#3fcc6c", "#dfa93f", "#3580c1", "#ac45cc", "#36b5a4", "#b5cdbd",
33 | "#636c7e", "#e15858", "#53db7f", "#daa640", "#4796d9", "#b057cb",
34 | "#51d5c3", "#51d5c3"],
35 | nord: @["#2e3440", "#3b4252", "#434c5e", "#4c566a", "#d8dee9", "#e5e9f0",
36 | "#eceff4", "#8fbcbb", "#88c0d0", "#81a1c1", "#5e81ac", "#bf616a",
37 | "#d08770",
38 | "#ebcb8b", "#a3be8c", "#b48ead"],
39 | everforest: @[
40 | "#d3c6aa", "#e67e80", "#e69875", "#dbbc7f", "#a7c080", "#83c092", "#7fbbb3",
41 | "#d699b6", "#7a8478", "#859289", "#9da9a0", "#f8f0dc", "#efead4", "#e9e5cf",
42 | "#e1ddc9", "#dcd8c4", "#b9c0ab", "#e6e9c4", "#f9e0d4", "#edeece", "#e7ede5", "#f6e9c9"
43 | ],
44 | ashes: @[
45 | "#1C2023", "#393F45", "#565E65", "#747C84", "#ADB3BA", "#C7CCD1", "#DFE2E5",
46 | "#F3F4F5", "#C7AE95", "#C7C795", "#AEC795", "#95C7AE", "#95AEC7", "#AE95C7",
47 | "#C795AE", "#C79595"
48 | ],
49 | tokyonight: @[
50 | "#f7768e", "#ff9e64", "#e0af68", "#9ece6a", "#73daca", "#b4f9f8", "#2ac3de",
51 | "#7dcfff", "#7aa2f7",
52 | "#bb9af7", "#c0caf5", "#a9b1d6", "#9aa5ce", "#cfc9c2", "#565f89", "#414868",
53 | "#24283b", "#1a1b26"
54 | ]
55 | )
56 |
57 |
--------------------------------------------------------------------------------
/lib/updates.nim:
--------------------------------------------------------------------------------
1 | import os, puppy, strutils, distros,
2 | strformat, zippy/ziparchives
3 |
4 | proc u*(v: string): void =
5 | let cv = fetch("https://raw.githubusercontent.com/Infinitybeond1/dye/main/dye.nimble").splitLines(
6 | )[0].split("=")[1].strip().replace("\"", "")
7 | if v.replace(".", "").strip().parseInt() < cv.replace(".", "").strip().parseInt():
8 | stdout.write("Updates are availible, would you like to update (Y/n): ")
9 | let a = readLine(stdin).toLower()
10 | if a == "n":
11 | echo "Exiting..."
12 | quit(0)
13 | let app = getAppFilename()
14 | echo "Detecting os..."
15 | var os: string
16 | if detectOs(Windows):
17 | echo "This feature isnt supported on windows"
18 | elif detectOs(Linux):
19 | os = "linux"
20 | elif detectOs(MacOSX):
21 | os = "darwin"
22 | else:
23 | quit 1
24 | echo "Downloading file..."
25 | writeFile(getTempDir() / fmt"dye-{os}.zip", fetch(fmt"https://github.com/Infinitybeond1/dye/releases/download/v{cv.strip()}/dye-{os}.zip"))
26 | while true:
27 | if fileExists(getTempDir() / fmt"dye-{os}.zip"):
28 | break
29 | let file = getTempDir() / fmt"dye-{os}.zip"
30 | echo "Extracting..."
31 | extractAll(file, getTempDir() / "dye")
32 | removeFile(file)
33 | echo "Moving file..."
34 | removeFile(app)
35 | copyFileWithPermissions(getTempDir() / "dye" / "dye", app)
36 | removeDir(getTempDir() / "dye")
37 | echo "Completed!"
38 | elif v.replace(".", "").strip().parseInt() == cv.replace(".", "").strip().parseInt():
39 | echo "You're all up to date"
40 | else:
41 | echo "Your version: $#\nCurrent version: $#" % @[v, cv]
42 |
43 |
--------------------------------------------------------------------------------
/scripts/zigcc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | zig cc $@
3 |
--------------------------------------------------------------------------------
/src/dye.nim:
--------------------------------------------------------------------------------
1 | # Most of the comments in the code are echo statements for debug purposes.
2 | import os,
3 | chroma,
4 | pixie,
5 | strutils,
6 | progress,
7 | terminal,
8 | strformat
9 |
10 | include ../lib/args
11 |
12 | import ../lib/[colors, palettes, updates]
13 |
14 | var
15 | flipName: string
16 | convName: string
17 | lumaName: string
18 |
19 | var outfile: string
20 | var fileDir: string
21 |
22 | if args.flip.seen:
23 | outfile = flip.output.value
24 | fileDir = flip.file.value
25 | elif args.luma.seen:
26 | outfile = luma.output.value
27 | fileDir = luma.file.value
28 | else:
29 | outfile = args.output.value
30 | fileDir = args.file.value
31 |
32 | proc fileName(file: string, outfile: string): void =
33 | if outfile != "null":
34 | flipName = outfile & ".png"
35 | convName = outfile & ".png"
36 | lumaName = outfile & ".png"
37 | else:
38 | flipName = "flip-" & getFilename(file) & ".png"
39 | convName = "conv-" & getFilename(file) & ".png"
40 | lumaName = "luma-" & getFilename(file) & ".png"
41 |
42 | proc addFiles(fileDir: string): seq[string] =
43 | if dirExists(fileDir):
44 | if args.recursive.seen:
45 | for file in walkDirRec(fileDir):
46 | if file.splitFile().ext in [".png", ".jpg", ".jpeg"]:
47 | result.add(file)
48 | else:
49 | for file in walkDir(fileDir):
50 | if file.path.splitFile().ext in [".png", ".jpg", ".jpeg"]:
51 | result.add(file.path)
52 | else:
53 | result.add(fileDir)
54 |
55 | proc flipCol(imgPath: string, bar: bool): void =
56 | stdout.styledWriteLine(fgYellow, "Converting: ", fgWhite, splitFile(
57 | imgPath).name & splitFile(imgPath).ext & " ...")
58 | if bar:
59 | var imageFile = readImage(imgPath)
60 | var newImg = copy(imageFile)
61 | var bar = newProgressBar(total = imageFile.width * imageFile.height)
62 | bar.start()
63 | for y in 1..newImg.height:
64 | for x in 1..newImg.width:
65 | var rgbx = newImg.getColor(x, y).rgbx()
66 | rgbx.r = 255 - rgbx.r
67 | rgbx.g = 255 - rgbx.g
68 | rgbx.b = 255 - rgbx.b
69 | newImg.setColor(x, y, rgbx.color)
70 | bar.increment()
71 | bar.finish()
72 | stdout.styledWriteLine(fgGreen, "Completed: ", fgWhite, splitFile(
73 | imgPath).name & splitFile(imgPath).ext & "\n")
74 | fileName(imgPath, flip.output.value)
75 | newImg.save(flipName)
76 | else:
77 | var imageFile = readImage(imgPath)
78 | var newImg = copy(imageFile)
79 | for y in 1..newImg.height:
80 | for x in 1..newImg.width:
81 | var rgbx = newImg.getColor(x, y).rgbx()
82 | rgbx.r = 255 - rgbx.r
83 | rgbx.g = 255 - rgbx.g
84 | rgbx.b = 255 - rgbx.b
85 | newImg.setColor(x, y, rgbx.color)
86 | stdout.styledWriteLine(fgGreen, "Completed: ", fgWhite, splitFile(
87 | imgPath).name & splitFile(imgPath).ext & "\n")
88 | fileName(imgPath, flip.output.value)
89 | newImg.save(flipName)
90 |
91 | proc lumaCol(imgPath: string, bar: bool): void =
92 | stdout.styledWriteLine(fgYellow, "Converting: ", fgWhite, splitFile(
93 | imgPath).name & splitFile(imgPath).ext & " ...")
94 | if bar:
95 | var imageFile = readImage(imgPath)
96 | var newImg = copy(imageFile)
97 | var bar = newProgressBar(total = imageFile.width * imageFile.height)
98 | bar.start()
99 | for y in 1..newImg.height:
100 | for x in 1..newImg.width:
101 | #echo 1 - hsl(newImg.getColor(x, y)).l / 100
102 | newImg.setColor(x, y, newImg.getColor(x, y).invertLuma())
103 | #echo -(newImg.getColor(x, y).hsl().l / 100)
104 | bar.increment()
105 | bar.finish()
106 | stdout.styledWriteLine(fgGreen, "Completed: ", fgWhite, splitFile(
107 | imgPath).name & splitFile(imgPath).ext & "\n")
108 | fileName(imgPath, luma.output.value)
109 | newImg.save(lumaName)
110 | else:
111 | var imageFile = readImage(imgPath)
112 | var newImg = copy(imageFile)
113 | for y in 1..newImg.height:
114 | for x in 1..newImg.width:
115 | #echo 1 - hsl(newImg.getColor(x, y)).l / 100
116 | newImg.setColor(x, y, newImg.getColor(x, y).invertLuma())
117 | #echo -(newImg.getColor(x, y).hsl().l / 100)
118 | stdout.styledWriteLine(fgGreen, "Completed: ", fgWhite, splitFile(
119 | imgPath).name & splitFile(imgPath).ext & "\n")
120 | fileName(imgPath, luma.output.value)
121 | newImg.save(lumaName)
122 |
123 | proc col(imgPath: string, bar: bool, colors: seq[string]): void =
124 | stdout.styledWriteLine(fgYellow, "Converting: ", fgWhite, splitFile(
125 | imgPath).name & splitFile(imgPath).ext & " ...")
126 | fileName(imgPath, args.output.value)
127 | if bar:
128 | var imageFile = readImage(imgPath)
129 | let h = imageFile.height
130 | let w = imageFile.width
131 | let colorsRGB = colors.prepareClosestColor()
132 | var newImg = copy(imageFile)
133 | var bar = newProgressBar(total = h)
134 | bar.start()
135 | for y in 1..h:
136 | for x in 1..w:
137 | newImg.setColor(x = x, y = y, color = getClosestColor(colorsRGB,
138 | newImg.getColor(x, y)))
139 | bar.increment()
140 | newImg.save(convName)
141 | bar.finish()
142 | stdout.styledWriteLine(fgGreen, "Completed: ", fgWhite, splitFile(
143 | imgPath).name & splitFile(imgPath).ext & "\n")
144 | else:
145 | var imageFile = readImage(imgPath)
146 | let h = imageFile.height
147 | let w = imageFile.width
148 | let colorsRGB = colors.prepareClosestColor()
149 | var newImg = copy(imageFile)
150 | for y in 1..h:
151 | for x in 1..w:
152 | newImg.setColor(x = x, y = y, color = getClosestColor(
153 | colorsRGB, newImg.getColor(x, y)))
154 | newImg.save(convName)
155 | stdout.styledWriteLine(fgGreen, "Completed: ", fgWhite, splitFile(
156 | imgPath).name & splitFile(imgPath).ext & "\n")
157 |
158 | if args.flip.seen:
159 | for img in addFiles(flip.file.value):
160 | try:
161 | flipCol(img, flip.bar.seen)
162 | except:
163 | stdout.styledWriteLine(fgRed, "Error: ", fgWhite, getCurrentExceptionMsg(), "\n")
164 | continue
165 | elif args.update.seen:
166 | u(versionNum)
167 | elif args.luma.seen:
168 | for img in addFiles(luma.file.value):
169 | try:
170 | lumaCol(img, luma.bar.seen)
171 | except:
172 | stdout.styledWriteLine(fgRed, "Error: ", fgWhite, getCurrentExceptionMsg(), "\n")
173 | continue
174 | elif args.list.seen:
175 | for k, v in pal.fieldPairs:
176 | discard v
177 | echo k
178 | else:
179 | var cols: seq[string]
180 | if "," in args.palette.value:
181 | cols = args.palette.value.parseColors()
182 | elif fileExists(args.palette.value):
183 | cols = readFile(args.palette.value).parseColors()
184 | else:
185 | for k, v in pal.fieldPairs:
186 | if args.palette.value == k:
187 | cols = v
188 | break
189 | cols = cols.rmTag()
190 | for img in addFiles(args.file.value):
191 | try:
192 | col(img, args.bar.seen, cols)
193 | except:
194 | stdout.styledWriteLine(fgRed, "Error: ", fgWhite, getCurrentExceptionMsg(), "\n")
195 | continue
196 |
--------------------------------------------------------------------------------