barf 1.0.5 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/barf.gemspec +4 -7
- data/lib/barf/rgb_to_ansi.rb +96 -0
- data/lib/barf/version.rb +6 -1
- data/lib/barf.rb +1 -2
- metadata +20 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a54ef7a9bc1c444deb287dcb2e251c5b3d1f6b2faabb98193e213381e7260832
|
4
|
+
data.tar.gz: 4ddbc68c83504e5e024cb3099924bf91c1f019338d5e3cb93a865b621b1abe0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5af52fd5dc2498c4828ec123ab6a4d8c578788ab4e09485dbc9405fd47c7b0b7ce29aaaad5189a35dd6031ea74e20b91abb89f84b6305b383b4f12b2163168dd
|
7
|
+
data.tar.gz: 778b824ebc858733f9dadfbb433236fd47c62800dd1e0af99b13a0f20c33d90228ddc1981bdd238aefa5d30305a875f78422b0223816551dbdf4f02c64bf7f80
|
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[](https://hakiri.io/github/duffyjp/barf/master)
|
2
|
+
|
1
3
|
# Barf
|
2
4
|
|
3
5
|
Displays images in your terminal. There are many existing utilities to
|
@@ -17,7 +19,7 @@ accomplish this, but they're all way too complex.
|
|
17
19
|
## Details
|
18
20
|
* Can display anything supported by imagemagick including web resources.
|
19
21
|
* Applies the 256 color extended Ansi color palette with dithering.
|
20
|
-
* Multithreading is used to speed up
|
22
|
+
* Multithreading is used to speed things up.
|
21
23
|
|
22
24
|
```bash
|
23
25
|
$ barf https://avatars2.githubusercontent.com/u/382216
|
data/barf.gemspec
CHANGED
@@ -23,13 +23,10 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
25
|
# Read and process images
|
26
|
-
spec.add_dependency "mini_magick"
|
26
|
+
spec.add_dependency "mini_magick", '>= 3.6.0'
|
27
27
|
spec.add_dependency "parallel"
|
28
28
|
|
29
|
-
|
30
|
-
spec.
|
31
|
-
|
32
|
-
spec.add_development_dependency "bundler", "~> 1.16"
|
33
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
34
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
29
|
+
spec.add_development_dependency "bundler"
|
30
|
+
spec.add_development_dependency "rake"
|
31
|
+
spec.add_development_dependency "rspec"
|
35
32
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
##
|
4
|
+
# A helper module to detect terminal capabilities.
|
5
|
+
module Terminal
|
6
|
+
# Checks if the terminal likely supports 24-bit "true color" by checking
|
7
|
+
# the standard COLORTERM environment variable. Works in iTerm, MacOS Terminal does not as of 2025.
|
8
|
+
def self.truecolor?
|
9
|
+
ENV['COLORTERM'] =~ /^(truecolor|24bit)$/
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# Converts an RGB color to the nearest matching 8-bit ANSI terminal color code.
|
15
|
+
# This is now only used as a fallback for terminals without true color support.
|
16
|
+
class AnsiColorConverter
|
17
|
+
# Pre-calculated lookup table of the 256 ANSI colors and their RGB values.
|
18
|
+
ANSI_PALETTE = begin
|
19
|
+
cube_levels = [0, 95, 135, 175, 215, 255]
|
20
|
+
palette = [
|
21
|
+
[0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0],
|
22
|
+
[0, 0, 128], [128, 0, 128], [0, 128, 128], [192, 192, 192],
|
23
|
+
[128, 128, 128], [255, 0, 0], [0, 255, 0], [255, 255, 0],
|
24
|
+
[0, 0, 255], [255, 0, 255], [0, 255, 255], [255, 255, 255]
|
25
|
+
]
|
26
|
+
(0..5).each { |r| (0..5).each { |g| (0..5).each { |b| palette << [cube_levels[r], cube_levels[g], cube_levels[b]] } } }
|
27
|
+
(0..23).each { |step| level = 8 + (step * 10); palette << [level, level, level] }
|
28
|
+
palette.freeze
|
29
|
+
end.freeze
|
30
|
+
|
31
|
+
# Convenience class method for direct conversion.
|
32
|
+
def self.convert(r, g, b)
|
33
|
+
min_dist_sq = Float::INFINITY
|
34
|
+
alternate_code = -1
|
35
|
+
nearest_code = -1
|
36
|
+
ANSI_PALETTE.each_with_index do |(ar, ag, ab), code|
|
37
|
+
dist_sq = (r - ar)**2 + (g - ag)**2 + (b - ab)**2
|
38
|
+
alternate_code ||= code
|
39
|
+
nearest_code ||= code
|
40
|
+
next unless dist_sq < min_dist_sq
|
41
|
+
alternate_code = nearest_code
|
42
|
+
min_dist_sq = dist_sq
|
43
|
+
nearest_code = code
|
44
|
+
end
|
45
|
+
# Alternate color is chosen randomly to simulate dithering.
|
46
|
+
rand(2) == 0 ? nearest_code : alternate_code
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Extend Ruby's String class to add terminal color methods.
|
52
|
+
class String
|
53
|
+
# Matches an ANSI-wrapped string to allow for code chaining.
|
54
|
+
ANSI_COLOR_REGEX = /\A(\e\[[\d;]*m)(.*?)(\e\[0m)\z/m
|
55
|
+
|
56
|
+
# Sets the foreground color of the string using an RGB array.
|
57
|
+
# @param rgb_array [Array<Integer>] An array of [r, g, b] values (0-255).
|
58
|
+
# @return [String] The colorized string.
|
59
|
+
def fg(rgb_array)
|
60
|
+
apply_color('38', rgb_array)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Sets the background color of the string using an RGB array.
|
64
|
+
# @param rgb_array [Array<Integer>] An array of [r, g, b] values (0-255).
|
65
|
+
# @return [String] The colorized string.
|
66
|
+
def bg(rgb_array)
|
67
|
+
apply_color('48', rgb_array)
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
# Helper method to apply an ANSI color code to the string.
|
73
|
+
# It intelligently handles chained calls by combining ANSI codes.
|
74
|
+
def apply_color(type_code, rgb_array)
|
75
|
+
color_segment =
|
76
|
+
if Terminal.truecolor?
|
77
|
+
# Use 24-bit "true color" for perfect quality.
|
78
|
+
"#{type_code};2;#{rgb_array.join(';')}"
|
79
|
+
else
|
80
|
+
# Fallback to the 256-color palette for older terminals.
|
81
|
+
ansi_code = AnsiColorConverter.convert(*rgb_array)
|
82
|
+
"#{type_code};5;#{ansi_code}"
|
83
|
+
end
|
84
|
+
|
85
|
+
if (match = match(ANSI_COLOR_REGEX))
|
86
|
+
# String is already colorized, so we combine new and existing codes.
|
87
|
+
start_seq, content, end_seq = match.captures
|
88
|
+
existing_codes = start_seq[2..-2]
|
89
|
+
updated_codes = existing_codes.empty? ? color_segment : "#{existing_codes};#{color_segment}"
|
90
|
+
"\e[#{updated_codes}m#{content}#{end_seq}"
|
91
|
+
else
|
92
|
+
# String is not colorized, so we wrap it in new codes.
|
93
|
+
"\e[#{color_segment}m#{self}\e[0m"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/barf/version.rb
CHANGED
data/lib/barf.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative "./barf/version"
|
2
2
|
|
3
3
|
require "mini_magick"
|
4
|
-
|
4
|
+
require_relative "./barf/rgb_to_ansi"
|
5
5
|
require "parallel"
|
6
6
|
|
7
7
|
module Barf
|
@@ -18,7 +18,6 @@ module Barf
|
|
18
18
|
tmp.alpha 'remove'
|
19
19
|
tmp.flatten
|
20
20
|
tmp.resize "#{terminal_width}x#{new_height}!"
|
21
|
-
tmp.dither 'FloydSteinberg'
|
22
21
|
tmp.remap __dir__ + '/palette.png'
|
23
22
|
end
|
24
23
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: barf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jacob Duffy
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mini_magick
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 3.6.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 3.6.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: parallel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,62 +39,48 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
|
-
type: :
|
48
|
+
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: bundler
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.16'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.16'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: rake
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
|
-
- - "
|
59
|
+
- - ">="
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
61
|
+
version: '0'
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
|
-
- - "
|
66
|
+
- - ">="
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
68
|
+
version: '0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: rspec
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
|
-
- - "
|
73
|
+
- - ">="
|
88
74
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
75
|
+
version: '0'
|
90
76
|
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
|
-
- - "
|
80
|
+
- - ">="
|
95
81
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
97
|
-
description:
|
82
|
+
version: '0'
|
83
|
+
description:
|
98
84
|
email:
|
99
85
|
- duffy.jp@gmail.com
|
100
86
|
executables:
|
@@ -115,6 +101,7 @@ files:
|
|
115
101
|
- bin/setup
|
116
102
|
- exe/barf
|
117
103
|
- lib/barf.rb
|
104
|
+
- lib/barf/rgb_to_ansi.rb
|
118
105
|
- lib/barf/version.rb
|
119
106
|
- lib/palette.png
|
120
107
|
- lib/palette.txt
|
@@ -122,7 +109,7 @@ homepage: https://github.com/duffyjp/barf
|
|
122
109
|
licenses:
|
123
110
|
- MIT
|
124
111
|
metadata: {}
|
125
|
-
post_install_message:
|
112
|
+
post_install_message:
|
126
113
|
rdoc_options: []
|
127
114
|
require_paths:
|
128
115
|
- lib
|
@@ -137,9 +124,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
124
|
- !ruby/object:Gem::Version
|
138
125
|
version: '0'
|
139
126
|
requirements: []
|
140
|
-
|
141
|
-
|
142
|
-
signing_key:
|
127
|
+
rubygems_version: 3.4.10
|
128
|
+
signing_key:
|
143
129
|
specification_version: 4
|
144
130
|
summary: Output images in terminal
|
145
131
|
test_files: []
|