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

Here's a Perl script for taking an image and turning it into a shuffled grid puzzle like this. Print them out, give them to the kids with a suitable drawing implement and sit back to enjoy 5 minutes of peace and quiet. More examples here.

#!/usr/bin/perl -w # # This script was written by Grant McLean <grantm@cpan.org> # # Permission is hereby granted to use, modify and distribute it under +the same # terms as Perl itself. # use strict; use Image::Magick; use List::Util (); # For Win32, add folder containing ImageMagick DLLs to PATH $ENV{PATH} .= ';C:\Perl\site\lib\auto\Image\Magick'; my $page_width = 700; my $page_height = 1040; my $columns = 5; my $rows = 4; my $char_height = 20; my $pic_width = 400; my $pic_height = 300; my $pic_x = int(($page_width - ($pic_width + $char_height * ($co +lumns - 1))) / 2); my $pic_y = $char_height; my $input_file = shift or die "Usage: $0 filename.gif\n"; # Read in the source image and work out its dimensions my $err; my $src = Image::Magick->new; $err = $src->Read($input_file); die $err if($err); my $src_width = $src->Get('width'); my $src_height = $src->Get('height'); # Work out the scaled dimensions and resize the source my $pic_ratio = $pic_width / $pic_height; my $src_ratio = $src_width / $src_height; my($new_width, $new_height); if($pic_ratio > $src_ratio) { $new_height = $pic_height; $new_width = int($pic_height * $src_ratio); } else { $new_width = $pic_width; $new_height = int($pic_width / $src_ratio) + 1; } $src->Resize(width => $new_width, height => $new_height); # Pad the image out to an exact multiple of rows and cols my $pad = $rows + $columns; $src->Border(width => $pad, height => $pad, fill => 'white'); my $pad_width = int(($new_width + $columns - 1) / $columns) * $colum +ns; my $pad_height = int(($new_height + $rows - 1) / $rows) * $rows; $src->Crop( width => $pad_width, height => $pad_height, x => $pad - int(($pad_width - $new_width) / 2), y => $pad - int(($pad_height - $new_height) / 2), ); $new_width = $src->Get('width'); $new_height = $src->Get('height'); # Create a completely new image to paste the chunks into my $composite = Image::Magick->new(size => "${page_width}x${page_heigh +t}"); $composite->Read('xc:white'); # Build up a list of chunk coordinates and then shuffle them my $chunk_width = int($new_width / $columns); my $chunk_height = int($new_height / $rows ); my @row = qw(A B C D); my @cells; for(my $i = 0; $i < $rows; $i++) { for(my $j = 0; $j < $columns; $j++) { push @cells, { label => $row[$i] . ($j + 1), cx => $j * $chunk_width, cy => $i * $chunk_height, }; } } @cells = List::Util::shuffle(@cells); # Loop through carving off chunks and pasting them in for(my $i = 0; $i < @cells; $i++) { my $c = $cells[$i]; my $x = $pic_x + ($chunk_width + $char_height) * ($i % $columns); my $y = $pic_y + ($chunk_height + $char_height) * int($i / $columns) +; my $chunk = $src->Clone(); $chunk->Crop( width => $chunk_width, height => $chunk_height, x => $c->{cx}, y => $c->{cy}, ); $chunk->Border(width => 1, height => 1, fill => 'black'); $composite->Composite( image => $chunk, compose => 'Over', x => $x, y => $y, ); $composite->Annotate( text => $c->{label}, x => $x, y => $y - 1, font => 'Generic.ttf', fill => 'black', pointsize => 12, ); } # Calculate the dimensions of the blank grid at the bottom my $grid_x = 2 * $char_height; my $grid_y = $pic_y + $pic_height + ($rows + 1) * $char_height; my $grid_width = $page_width - 4 * $char_height; my $grid_height = $page_height - $grid_y - 1; if($grid_width / $src_ratio > $grid_height) { $grid_width = int($grid_height * $src_ratio); } else { $grid_height = int($grid_width / $src_ratio); } my $grid_ratio = $grid_width / $grid_height; my $cell_width = int($grid_width / $columns); my $cell_height = int($grid_height / $rows ); # Draw the horizontal lines my($points); for(my $i = 0; $i < $rows; $i++) { $composite->Annotate( text => $row[$i], x => $grid_x - $char_height, y => $grid_y + $i * $cell_height + int($cell_height / 2), font => 'Generic.ttf', fill => 'black', pointsize => 14, ); next if($i == 0); $points = sprintf("%d,%d %d,%d", $grid_x, $grid_y + $cell_height * $i, $grid_x + $grid_width, $grid_y + $cell_height * $i, ); $composite->Draw(primitive => 'line', stroke => '#CCC', points => $p +oints); } # Draw the vertical lines for(my $i = 0; $i < $columns; $i++) { $composite->Annotate( text => "" . $i + 1, x => $grid_x + $i * $cell_width + int($cell_width / 2), y => $grid_y - int($char_height / 4), font => 'Generic.ttf', fill => 'black', pointsize => 14, ); next if($i == 0); $points = sprintf("%d,%d %d,%d", $grid_x + $cell_width * $i, $grid_y, $grid_x + $cell_width * $i, $grid_y + $grid_height, ); $composite->Draw(primitive => 'line', stroke => '#CCC', points => $p +oints); } # Draw the box $points = sprintf("%d,%d %d,%d", $grid_x, $grid_y, $grid_x + $grid_width, $grid_y + $grid_height, ); $composite->Draw( primitive => 'rectangle', fill => 'none', stroke => 'black', points => $points, ); # Write out the composite file $err = $composite->Set(filename => 'composite.gif'); $err = $composite->Write('composite.gif'); #$err = $composite->Write('win:');

Replies are listed 'Best First'.
Re: Keep the kids amused
by chanio (Priest) on Apr 09, 2004 at 08:38 UTC
    Thank you!

    Works marvelous for the kids! (my puzzles are written in Perl :))

    Images might be collected from cartonnetworks.

Re: Keep the kids amused
by zentara (Archbishop) on Apr 09, 2004 at 16:32 UTC
    Very nice. If your kids are old enough to use the computer, or if they like the monitor more than paper, you can let them play this-> tk-picture-scramble-puzzle

    I'm not really a human, but I play one on earth. flash japh