http://qs321.pair.com?node_id=11148530

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.