Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Keep the kids amused

by grantm (Parson)
on Apr 09, 2004 at 04:55 UTC ( #343850=CUFP: print w/replies, xml ) Need Help??

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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://343850]
Approved by davido
Front-paged by PodMaster
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2022-01-19 18:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    In 2022, my preferred method to securely store passwords is:












    Results (55 votes). Check out past polls.

    Notices?