-
Notifications
You must be signed in to change notification settings - Fork 33
/
2x_zoom.pl
executable file
·122 lines (94 loc) · 2.71 KB
/
2x_zoom.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
118
119
120
121
122
#!/usr/bin/perl
# Daniel "Trizen" Șuteu
# License: GPLv3
# Date: 11 March 2017
# https://github.com/trizen
# A simple gap-filling algorithm for applying a 2x zoom to an image.
use 5.010;
use strict;
use warnings;
use Imager;
use List::Util qw(sum);
my $file = shift(@ARGV) // die "usage: $0 [image]\n";
my $img = Imager->new(file => $file)
or die Imager->errstr();
my $width = $img->getwidth;
my $height = $img->getheight;
my @matrix;
foreach my $y (0 .. $height - 1) {
foreach my $x (0 .. $width - 1) {
$matrix[$y][$x] = $img->getpixel(x => $x, y => $y);
}
}
my $out_img = Imager->new(xsize => 2 * $width,
ysize => 2 * $height);
sub gap_color {
my ($x, $y) = @_;
my @neighbors;
if ($y > 0) {
# Top neighbor
if ($x < $width) {
push @neighbors, $matrix[$y - 1][$x];
}
# Top-right neighbor
if ($x < $width - 1) {
push @neighbors, $matrix[$y - 1][$x + 1];
}
# Top-left neighbor
if ($x > 0) {
push @neighbors, $matrix[$y - 1][$x - 1];
}
}
if ($y < $height - 1) {
# Bottom neighbor
if ($x < $width) {
push @neighbors, $matrix[$y + 1][$x];
}
# Bottom-right neighbor
if ($x < $width - 1) {
push @neighbors, $matrix[$y + 1][$x + 1];
}
# Bottom-left neighbor
if ($x > 0) {
push @neighbors, $matrix[$y + 1][$x - 1];
}
}
if ($y < $height) {
# Left neighbor
if ($x > 0) {
push @neighbors, $matrix[$y][$x - 1];
}
# Right neighbor
if ($x < $width - 1) {
push @neighbors, $matrix[$y][$x + 1];
}
}
# Get the RGBA colors
my @colors = map { [$_->rgba] } @neighbors;
my @red = map { $_->[0] } @colors;
my @blue = map { $_->[1] } @colors;
my @green = map { $_->[2] } @colors;
my @alpha = map { $_->[3] } @colors;
#<<<
# Compute the average gap-filling color
my @gap_color = (
sum(@red ) / @red,
sum(@blue ) / @blue,
sum(@green) / @green,
sum(@alpha) / @alpha,
);
#>>>
return \@gap_color;
}
foreach my $y (0 .. $#matrix) {
foreach my $x (0 .. $#{$matrix[$y]}) {
#<<<
# Fill the gaps
$out_img->setpixel(x => 2 * $x, y => 2 * $y, color => $matrix[$y][$x]);
$out_img->setpixel(x => 2 * $x + 1, y => 2 * $y + 1, color => gap_color($x + 1, $y + 1));
$out_img->setpixel(x => 2 * $x + 1, y => 2 * $y, color => gap_color($x + 1, $y ));
$out_img->setpixel(x => 2 * $x, y => 2 * $y + 1, color => gap_color($x, $y + 1));
#>>>
}
}
$out_img->write(file => '2x_zoom.png');