Hello folks!
..since its raining.. :) inspired by my own challenge (yes: I feel brave enough!) I wrote a nice subroutine to tile images horizontally or vertically.
No need to get more complicate: if you need a tiled 3x3 image just build up three times a 3x1 and use them to create the 3x3 one.
Being the space divided evenly, if you pass images very different in shape the result will be ugly to see, but the sub is as much as generic it can.
Resulting dimensions will be adjusted pixel by pixel until they become evenly divisible for the number of images processed: so if you ask to create an image with 899 as width and 3 images you'll get an image of 900 pixel width
Here the small test script containing the gd_tiler sub and few line of code. Pass please as @ARGV 3 images of approximately same shape (or modify the code as you need.. it is free ;)
use strict;
use warnings;
use GD;
# for semplicity pass 3 images
my @test_images = ($ARGV[0],$ARGV[1],$ARGV[2]);
sub gd_tiler{
my %params = @_;
my $width = $params{width} or die "Missing width (or zero)!";
my $hight = $params{height} or die "Missing height (or zero)!";
my $direction = $params{direction};
my $format = defined $params{format} ? $params{format} : 'jpeg';
my $filename = $params{filename} or die "Missing filename for outp
+ut image";
my @images = ref $params{images} eq 'ARRAY' ?
@{$params{images}} :
die "Images should be passed as array reference!";
my $verbosity = $params{verbosity};
# offset used after
my $woffset = 0;
my $hoffset = 0;
# adjust for horizontal tiling
if ( $direction =~ /^h/i){
unless ( int($width / scalar @images) == ($width / scalar @ima
+ges) ){
$width++ until int($width / scalar @images) == ($width / s
+calar @images);
print "Adjusted width to $width..\n" if $verbosity;
$woffset = ($width / scalar @images);
}
$direction = 'h';
}
# adjust for vertical tiling
elsif ( $direction =~ /^v/i ){
unless ( int($hight / scalar @images) == ($hight / scalar @ima
+ges) ){
$hight++ until int($hight / scalar @images) == ($hight / s
+calar @images);
print "Adjusted hight to $hight..\n" if $verbosity;
$hoffset = ($hight / scalar @images);
}
$direction = 'v';
}
else { die "Unrecognized direction [$direction]! Should be 'horizo
+ntal' or 'vertical'" }
print "New image $filename ($width x $hight) will be tiled ",
( $direction eq 'v' ? "vertically" : "horizontally" ),
" using ",scalar @images," images\n" if $verbosity;
# default to truecolor
GD::Image->trueColor(1);
# resulting GD image
my $gdtiled = GD::Image->new($width, $hight);
my $count = 0;
foreach my $img( @images ){
die "Image [$img] not found!" unless -e $img;
print "\nProcessing $img" if $verbosity;
# transform into a GD object
# automatically recognized: GIF, PNG, JPEG, XBM, XPM, GD2, TIF
+F, WEBP, HEIF or AVIF
$img = GD::Image->new($img);
my $dstX = 0 + $woffset;
my $dstY = 0 + $hoffset;
my $srcX = 0;
my $srcY = 0;
my $destW = $direction eq 'h' ?
($width / scalar @images) :
$width;
my $destH = $direction eq 'v' ?
($hight / scalar @images) :
$hight;
my $srcW = $img->width();
my $srcH = $img->height();
if ( $verbosity ){
print " (",$img->width()," x ",$img->height(),")\n",
"destX $dstX\n",
"destY $dstY\n",
"srcX $srcX\nsrcY $srcY\n",
"destW $destW,\n",
"destH $destH\n",
"srcW $srcW\nsrcH $srcH\n";
}
# https://metacpan.org/pod/GD#$image-%3EcopyResampled($sourceI
+mage,$dstX,$dstY,
$gdtiled->copyResampled(
$img,
$dstX,
$dstY,
$srcX,
$srcY,
$destW,
$destH,
$srcW,
$srcH,
);
last if $count == $#images;
$count++;
# increment offset
if ( $direction eq 'h'){
$woffset += ($width / scalar @images);
print "(adjusting width offset += ".($width / scalar @imag
+es).")\n" if $verbosity;
}
else{
$hoffset += ($hight / scalar @images);
print "(adjusting hight offset += ".($hight / scalar @
+images).")\n" if $verbosity;
}
}
# write the output image
open my $out, '>', $filename or die "Unable to open [$filename] fo
+r writing!";
binmode $out;
die "Unsupported GD method [$format]!" unless $gdtiled->can($forma
+t);
print $out $gdtiled->$format or die "Error printing $gdtiled into
+$filename using $format!";
print "\nSuccesfully wrote $filename.\n\n" if $verbosity;
}
# horizontally
gd_tiler( width => 900,
height => 400,
direction => 'h',
format => 'jpeg',
filename => 'tiled-horizontally.jpg',
images => [ @test_images ],
verbosity => 1,
);
# vertically
gd_tiler( width => 300,
height => 1200,
direction => 'v',
format => 'jpeg',
filename => 'tiled-vertically.jpg',
images => [ @test_images ],
verbosity => 1,
);
# use the first one to build a 3x3 tiled
gd_tiler( width => 900,
height => 1200,
direction => 'v',
format => 'jpeg',
filename => 'tiled-3x3.jpg',
images => ['tiled-horizontally.jpg','tiled-horizon
+tally.jpg','tiled-horizontally.jpg' ],
verbosity => 1,
);
If you are too lazy to run it, here the output calling the program as: perl gd-tiler01.pl uno.jpg DSCN0077.JPG uno.jpg
New image tiled-horizontally.jpg (900 x 400) will be tiled horizontall
+y using 3 images
Processing uno.jpg (300 x 400)
destX 0
destY 0
srcX 0
srcY 0
destW 300,
destH 400
srcW 300
srcH 400
(adjusting width offset += 300)
Processing DSCN0077.JPG (3864 x 5152)
destX 300
destY 0
srcX 0
srcY 0
destW 300,
destH 400
srcW 3864
srcH 5152
(adjusting width offset += 300)
Processing uno.jpg (300 x 400)
destX 600
destY 0
srcX 0
srcY 0
destW 300,
destH 400
srcW 300
srcH 400
Succesfully wrote tiled-horizontally.jpg.
New image tiled-vertically.jpg (300 x 1200) will be tiled vertically u
+sing 3 images
Processing uno.jpg (300 x 400)
destX 0
destY 0
srcX 0
srcY 0
destW 300,
destH 400
srcW 300
srcH 400
(adjusting hight offset += 400)
Processing DSCN0077.JPG (3864 x 5152)
destX 0
destY 400
srcX 0
srcY 0
destW 300,
destH 400
srcW 3864
srcH 5152
(adjusting hight offset += 400)
Processing uno.jpg (300 x 400)
destX 0
destY 800
srcX 0
srcY 0
destW 300,
destH 400
srcW 300
srcH 400
Succesfully wrote tiled-vertically.jpg.
New image tiled-3x3.jpg (900 x 1200) will be tiled vertically using 3
+images
Processing tiled-horizontally.jpg (900 x 400)
destX 0
destY 0
srcX 0
srcY 0
destW 900,
destH 400
srcW 900
srcH 400
(adjusting hight offset += 400)
Processing tiled-horizontally.jpg (900 x 400)
destX 0
destY 400
srcX 0
srcY 0
destW 900,
destH 400
srcW 900
srcH 400
(adjusting hight offset += 400)
Processing tiled-horizontally.jpg (900 x 400)
destX 0
destY 800
srcX 0
srcY 0
destW 900,
destH 400
srcW 900
srcH 400
Succesfully wrote tiled-3x3.jpg.
L*
There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.