-
Notifications
You must be signed in to change notification settings - Fork 33
/
gd_star_trails.pl
executable file
·117 lines (91 loc) · 3.09 KB
/
gd_star_trails.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/perl
# Author: Daniel "Trizen" Șuteu
# License: GPLv3
# Date: 30 January 2015
# Edited: 31 January 2015
# Website: https://github.com/trizen
# Merge two or more images together and keep the most intensive pixel colors
use 5.010;
use strict;
use autodie;
use warnings;
use GD;
use Getopt::Long qw(GetOptions);
GD::Image->trueColor(1);
my $output_file = 'output.png';
my $file_format = 'png';
my $png_compression = 9;
my $jpeg_quality = 90;
my $scale_percent = 0;
sub help {
print <<"HELP";
usage: $0 [options] [files]
options:
-o --output : output file (default: $output_file)
-f --format : image format (default: $file_format)
-q --jpeg-quality : JPEG quality (default: $jpeg_quality)
-c --png-compression : PNG compression level (default: $png_compression)
-s --scale-percent : scale image by a given percentage (default: $scale_percent)
example:
$0 -o merged.png --scale -20 file1.jpg file2.jpg
HELP
exit;
}
GetOptions(
'o|output=s' => \$output_file,
'f|format=s' => \$file_format,
'q|jpeg-quality=i' => \$jpeg_quality,
'c|png-compression=i' => \$png_compression,
's|scale-percent=i' => \$scale_percent,
'h|help' => \&help,
)
or die "Error in command-line arguments!";
sub intensity {
($_[0] + $_[1] + $_[2]) / 3;
}
my @matrix;
my %color_cache;
my %intensity_cache;
foreach my $image (@ARGV) {
say "** Processing file: $image";
my $gd = GD::Image->new($image) // do {
warn "** Can't load file <<$image>>. Skipping...\n";
next;
};
my ($width, $height) = $gd->getBounds;
if ($scale_percent != 0) {
my $scale_width = $width + int($scale_percent / 100 * $width);
my $scale_height = $height + int($scale_percent / 100 * $height);
my $scaled_gd = GD::Image->new($scale_width, $scale_height);
$scaled_gd->copyResampled($gd, 0, 0, 0, 0, $scale_width, $scale_height, $width, $height);
($width, $height) = ($scale_width, $scale_height);
$gd = $scaled_gd;
}
foreach my $x (0 .. $width - 1) {
foreach my $y (0 .. $height - 1) {
my $index = $gd->getPixel($x, $y);
$matrix[$x][$y] //= [0, 0, 0];
if (intensity(@{$matrix[$x][$y]}) <
($intensity_cache{$index} //= (intensity(@{$color_cache{$index} //= [$gd->rgb($index)]})))) {
$matrix[$x][$y] = $color_cache{$index};
}
}
}
}
@matrix || die "error: No image has been processed!\n";
say "** Creating the output image: $output_file";
my $image = GD::Image->new($#matrix + 1, $#{$matrix[0]} + 1);
foreach my $x (0 .. $#matrix) {
my $row = $matrix[$x] // next;
foreach my $y (0 .. $#{$matrix[0]}) {
my $entry = $row->[$y] // next;
my $color = $image->colorAllocate(@{$entry});
$image->setPixel($x, $y, $color);
}
}
open my $fh, '>:raw', $output_file;
print $fh lc($file_format) =~ /png/
? $image->png($png_compression)
: $image->jpeg($jpeg_quality);
close $fh;
say "** All done!";