-
Notifications
You must be signed in to change notification settings - Fork 0
/
watermark-images.pl
162 lines (146 loc) · 5.33 KB
/
watermark-images.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/perl
use strict;
use Socket;
use GD;
use Image::Resize;
use POSIX;
# CONFIG
my $backup_dir = '/path/to/backup/dir';
my $watermark_image = '/path/to/watermark/file/watermark.png';
# Do not watermark images smaller than (pixels):
my $min_height = 75;
my $min_width = 200;
# CONFIG END, no need to edit beyond this line
my $basepath = $ARGV[0];
my $command = $ARGV[1];
if (!$basepath) {
die "Usage: watermark-images.pl /path/to/image/dir [safe|restore]
safe - make an additional back up of all files in image dir using gzip
(this is *in addition* to the regular backup)
restore - restore image files from the regular backup
(backups created in 'safe' mode have to be restored manually)\n\n";
}
if (!(-d $basepath)) {
die $basepath.' is not a directory.';
}
print "Running watermarking program\n";
my $fixed=0;
my $total=0;
if ($command eq 'safe'){
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year+=1900;
$mon=sprintf "%02d", $mon+1;
$mday=sprintf "%02d", $mday+1;
print "\nBacking up all files.\n";
`tar -cpvzf $backup_dir/backup_images_$year-$mon-$mday-$hour-$min-$sec.tgz $basepath/*`;
}
# Read the base dir for jpg files
opendir THEDIR, "$basepath";
my @allfiles = grep (/\.(jpe?g|png)$/i, sort { uc($a) cmp uc($b) } (readdir THEDIR));
closedir THEDIR;
print "\nWatermarking files in $basepath:\n";
# if commandline argument is restore, restore backed-up files
if ($command eq 'restore'){
foreach my $file (@allfiles) {
$total++;
if ($file =~ /^_/){
my $restore_file=$file;
$restore_file=~s/^_//;
`cp -f $basepath/$file $basepath/$restore_file`;
`rm -f $basepath/$file`;
print "Restored file $restore_file\n";
$fixed++;
}
}
# else watermark images
} else {
foreach my $file (@allfiles) {
$total++;
if ($file !~ /^_/){
print &watermark($basepath, $file, 'horizontal', '0.5,-10', 25);
$fixed++;
}
}
}
print "\nError code ", $? >> 8, ".\n";
print "Went through $total total files. $fixed were not backups.\n";
# Watermarking subroutine
sub watermark {
my ($basepath, $filename, $orientation, $positions, $transparency) = @_;
my ($position_x, $position_y) = split(/,/,$positions);
my ($iw, $is);
my $percent = $transparency; # transparency
# set-up
my $backup_file = "_$filename";
GD::Image->trueColor(1);
# open source image
$is = GD::Image->new("$basepath/$filename") or die("Failed to open \"$filename\"");
# open watermark image
$iw = GD::Image->new($watermark_image) or die("Failed to open \"$watermark_image\"");
# check that we haven't already watermarked this image
if (-e "$basepath/$backup_file"){
my $img = GD::Image->new("$basepath/$backup_file") or die("Failed to open \"$backup_file\"");
if ($img->height == $is->height and $img->width == $is->width){
return "$filename is already watermarked.\n";
}
}
# check that this image is big enough to be watermarked
if ($is->width < $min_width or $is->height < $min_height){
return "$filename is too small to watermark.\n";
} elsif ($is->width < $iw->width){
$iw = Image::Resize->new($iw);
$iw = $iw->resize($is->width,26);
}
# adjust parameters
if ($orientation eq 'vertical') { $iw = $iw->copyRotate270(); }
if ($position_x < 0){ $position_x = $is->width + $position_x - $iw->width; }
elsif ($position_x < 1){ $position_x = floor($is->width * $position_x - $iw->width / 2); }
if ($position_y < 0){ $position_y = $is->height + $position_y - $iw->height; }
elsif ($position_y < 1){ $position_y = floor($is->height * $position_y - $iw->height / 2); }
# printf("iw->trueColor() = %d$/", $iw->trueColor());
# printf("is->trueColor() = %d$/", $is->trueColor());
# Turn off alpha-blending temporarily for the watermark image. If
# we don't do this here, as we adjust each pixel colour and call
# setPixel(), GD will go through gdAlphaBlend() process for the
# current pixel colour and what we want to set the colour to.
$iw->alphaBlending(0);
# Go through every pixel in the watermark image and adjust the
# alpha channel value appropriately.
$percent /= 100.0;
for (my $h = 0; $h < $iw->height; ++$h) {
for (my $x = 0; $x < $iw->width; ++$x) {
my ($px, $alpha);
# Get pixel's colour value (a.k.a., index)
$px = $iw->getPixel($x, $h);
# Get the alpha channel value
$alpha = ($px >> 24) & 0xff;
# If it is completely transparent (0x7f = 127) skip
if ($alpha == 127) { next; }
$alpha += int((127 - $alpha) * $percent);
$alpha = 127 if ($alpha > 127); # Cap (paranoia)
# Adjust the new colour value based on the adjusted
# alpha channel value and set it.
$px = ($px & 0x00ffffff) | ($alpha << 24);
$iw->setPixel($x, $h, $px);
}
}
# Turn on alpha-blending now.
$iw->alphaBlending(1);
# copy watermark onto source image
$is->copy($iw, $position_x, $position_y, 0, 0, $iw->width, $iw->height);
# back up the file now
`cp -f $basepath/$filename $basepath/$backup_file`;
# If there was no error
if ($? != -1) {
# open destination/out file for writing
open(OUT, ">$basepath/$filename") or die("Failed to write \"$filename\": $!");
binmode OUT;
# write out resulting image
if ($filename=~/\.jpe?g$/) { print OUT $is->jpeg(80); }
elsif ($filename=~/\.png$/) { print OUT $is->png(5); }
close(OUT);
return("$filename watermarked successfully!\n");
} else {
return("Failed to create backup for $filename.\n");
}
}