some years ago I wrote perl subprograms for the 17 eucledian symmetry groups. They worked sufficient for my art context but the groups based on non 90° and 45° angles have some minor artefacts. For one typ of those artefacts (black pixels at the edges were two triangles were composed) I have found workarounds but for an other type (it seems that some triangles are not accurately fitting but they were composed correctly) I could not solve it. Now I want to take those loose ends and solve this.
Below I have copied the code to a script with the p6m subprogram (based on the p3m1 tile type), were the remaining artefact can be easier be detected than in other tile types. I have also posted (temporary) 3 p6m tiles on http://www.flickr.com/photos/gbachelier were those artefacts can be seen.
Could someone help me with this?
Thank you very much!
Guenter
Code: Select all
#!/usr/bin/perl
# generating p6m tile on the basis of p3m1 tile
# goal is to avoid artefacts (not accurately fitting image parts)
# - in $p6m_tile_part right in diagonal between G2 and G5_half
# - in $p6m_tile_row between p3m1_tile_part and p3m1_tile_part_flip
use diagnostics; use Image::Magick; srand;
###NEW IM-OBJECTS #######################################################################################################################################################
my $image = new Image::Magick; my $layer = new Image::Magick;
###NEW IM-OBJECTS #######################################################################################################################################################
my $input_image_path = '/home/ ...';
my $outputfolder_path = '/home/...'; # path without a last "/ "
# READ IMAGE IN $layer
$image->Read("$input_image_path");
for ($t = 0; $t <= 2; $t++) {
$layer = $image->Clone();
# EXTRACT SQUARE
($l_width, $l_height) = $layer->Get('columns', 'rows');
if ($l_width >= $l_height) {
$crop_value = $l_height;
$x_rand = int(rand($l_width - $l_height));
$layer->Crop(geometry=>"$crop_value x $crop_value +$x_rand +0");
} else {
$crop_value = $l_width;
$y_rand = int(rand($l_height - $l_width));
$layer->Crop(geometry=>"$crop_value x $crop_value +0 +$y_rand");
};
$layer->Set(page=>'0x0+0+0');
# MAKE TILE
& p6m;
$layer->Write(filename=>"$outputfolder_path/p6m_tile_$t.jpg", compression=>'JPEG', quality=>'95');
# DELETE OBJECTS RELATED TO ITERATION $t
@$layer = ();
};
# SUBPROGRAMS **************************************************************************************************************************************
# **************************************************************************************************************************************************
# p6m
# **************************************************************************************************************************************************
# **************************************************************************************************************************************************
sub p6m {
@_ = ($layer);
my($p6m_triangle_width, $p6m_triangle_height, $p3m1_G2_width_rotated, $p3m1_G2_cropwidth);
# RROGRAM ****************************************************************************************************
$image_p6m = new Image::Magick; $p6m_mask = new Image::Magick; $transparent_extention = new Image::Magick;
$image_p6m = $layer->Clone(); #$image_p6m->Write(filename=>'image_p6m.jpg', compression=>'JPEG', quality=>'95');
# GENERATE p6m_mask
($image_p6m_width, $image_p6m_height) = $image_p6m->Get('columns', 'rows'); print "sub(p6m): image_p6m_width=$image_p6m_width image_p6m_height=$image_p6m_height \n";
$p6m_triangle_height = $image_p6m_height;
$p6m_triangle_width = int(1/sqrt(3) * $p6m_triangle_height)+1; print "sub(p6m): p6m_triangle_width=$p6m_triangle_width p6m_triangle_height=$p6m_triangle_height \n";
$p6m_mask->Set(size=>"$p6m_triangle_width x $p6m_triangle_height");
$p6m_mask->Read('xc:none');
$p6m_mask->Draw(primitive=>'polyline', points=>"0,0 $p6m_triangle_width,$p6m_triangle_height 0,$p6m_triangle_height", fill=>'red');
#$p6m_mask->Write(filename=>'p6m_mask.jpg', compression=>'JPEG', quality=>'95');
# GENERATE p6m_G1
$p6m_G1 = $p6m_mask->Clone();
$p6m_G1->Composite(image=>$image_p6m, compose=>'in', color=>'transparent', matte=>'true');
$p6m_G1->Set(page=>'0x0+0+0'); #$p6m_G1->Write(filename=>'p6m_G1.jpg', compression=>'JPEG', quality=>'95');
# GENERATE p3m1_G4 (!!!!!p3m1 is right!!!!!)
$p6m_G1_flop = $p6m_G1->Clone();
$p6m_G1_flop->Flop();
$q = $p6m_G1_flop->Clone();
push(@$q, $p6m_G1);
$p3m1_G4 = $q->Append(stack=>'false'); #$p3m1_G4->Write(filename=>'p3m1_p6m_G4.jpg', compression=>'JPEG', quality=>'95');
# GENERATE p3m1_G1 (!!!!!p3m1 is right!!!!!)
$p3m1_G1 = $p3m1_G4->Clone();
$p3m1_G1->Flip(); #$p3m1_G1->Write(filename=>'p3m1_p6m_G1.jpg', compression=>'JPEG', quality=>'95');
# GENERATE p3m1_G2 (!!!!!p3m1 is right!!!!!)
$p3m1_G2 = $p3m1_G1->Clone();
$p3m1_G2->Flop();
$p3m1_G2->Rotate(degrees=>60, color=>'transparent');
$p3m1_G2->Set(page=>'0x0+0+0');
$p3m1_G2_width_rotated = $p3m1_G2->Get('columns');
$triangle_newwidth = 2 * $p6m_triangle_width;
$p3m1_G2_cropwidth = $p3m1_G2_width_rotated - $triangle_newwidth;
$p3m1_G2->Crop(geometry=>"$triangle_newwidth x $p6m_triangle_height + $p3m1_G2_cropwidth+0", background=>'transparent');
$p3m1_G2->Set(page=>'0x0+0+0'); #$p3m1_G2->Write(filename=>'p3m1_p6m_G2.jpg', compression=>'JPEG', quality=>'95');
# GENERATE p3m1_G6 (!!!!!p3m1 is right!!!!!)
$p3m1_G6 = $p3m1_G1->Clone();
$p3m1_G6->Flop();
$p3m1_G6->Rotate(degrees=>-60, color=>'transparent');
$p3m1_G6->Set(page=>'0x0+0+0');
$p3m1_G6->Crop(geometry=>"$triangle_newwidth x $p6m_triangle_height+0+0", background=>'transparent');
$p3m1_G6->Set(page=>'0x0+0+0'); #$p3m1_G6->Write(filename=>'p3m1_p6m_G6.jpg', compression=>'JPEG', quality=>'95');
# GENERATE p3m1_G5 (!!!!!p3m1 is right!!!!!)
$p3m1_G5 = $p3m1_G6->Clone();
$p3m1_G5->Flip(); #$p3m1_G5->Write(filename=>'p3m1_p6m_G5.jpg', compression=>'JPEG', quality=>'95');
# GENERATE p3m1_tile_part corrected (!!!!!p3m1 is right!!!!!)
$p3m1_G6h = $p3m1_G6->Clone();
$p3m1_G6h->Crop(geometry=>"$p6m_triangle_width x $p6m_triangle_height + $p6m_triangle_width+0", background=>'transparent');
$p3m1_G6h->Set(page=>'0x0+0+0');
$p3m1_G6h_width = $p3m1_G6h->Get('columns');
$p3m1_G6h_height = $p3m1_G6h->Get('rows');
$p3m1_G6h_zoomwidth = $p3m1_G6h_width + 2;
$p3m1_G6h->Zoom(width=>"$p3m1_G6h_zoomwidth", height=>"$p3m1_G6h_height");
$p3m1_tile_part = $p3m1_G1->Clone();
#$p3m1_tile_part->Composite(image=>$p3m1_G6h, gravity=>'West', compose=>'over', color=>'transparent', matte=>'true');
$p3m1_tile_part->Composite(image=>$p3m1_G6h, gravity=>'West', x => '-2', compose=>'over', color=>'transparent', matte=>'true'); #new!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$p3m1_tile_part->Set(page=>'0x0+0+0');
$transparent_extention->Set(size=>"$p6m_triangle_width x $p6m_triangle_height");
$transparent_extention->Read('xc:none');
@$q = ();
$q = $p3m1_tile_part->Clone();
push(@$q, $transparent_extention);
$p3m1_tile_part = $q->Append(stack=>'false');
$p3m1_tile_part->Composite(image=>$p3m1_G2, gravity=>'East', compose=>'over', color=>'transparent', matte=>'true');
$p3m1_tile_part->Set(page=>'0x0+0+0');
$p3m1_G5h = $p3m1_G5->Clone();
$p3m1_G5h->Crop(geometry=>"$p6m_triangle_width x $p6m_triangle_height+0+0",background=>'transparent');
$p3m1_G5h->Set(page=>'0x0+0+0');
($p3m1_G5h_width, $p3m1_G5h_height) = $p3m1_G5h->Get('columns', 'rows');
$p3m1_G5h_zoomwidth = $p3m1_G5h_width + 2;
$p3m1_G5h_zoomheight = $p3m1_G5h_height + 2;
$p3m1_G5h->Zoom(width=>"$p3m1_G5h_zoomwidth", height=>"$p3m1_G5h_zoomheight");
$p3m1_G5h->Set(page=>'0x0+0+0');
#$p3m1_tile_part->Composite(image=>$p3m1_G5h, gravity=>'East', compose=>'over', color=>'transparent', matte=>'true');
$p3m1_tile_part->Composite(image=>$p3m1_G5h, gravity=>'East', x => '+1', y => '+1', compose=>'over', color=>'transparent', matte=>'true'); #new!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$p3m1_tile_part->Set(page=>'0x0+0+0');
my $p3m1_tile_part_w = $p3m1_tile_part->Get('columns'); #new!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$p3m1_tile_part->Crop(geometry=>"$p3m1_tile_part_w x $p6m_triangle_height+2+0",background=>'transparent');#new!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$p3m1_tile_part->Set(page=>'0x0+0+0');
#$p3m1_tile_part->Write(filename=>"$outputfolder_path/p3m1_tile_part_$t.jpg", compression=>'JPEG', quality=>'95');
# GENERATE p3m1_tile_part_flip (!!!!!p3m1 is right!!!!!)
$p3m1_tile_part_flip = $p3m1_tile_part->Clone();
$p3m1_tile_part_flip->Flip(); #$p3m1_tile_part_flip->Write(filename=>'p3m1_p6m_tile_part_flip.jpg', compression=>'JPEG', quality=>'95');
# GENERATE p3m1_tile_row (!!!!!p3m1 is right!!!!!)
@$q = ();
$q = $p3m1_tile_part->Clone();
push(@$q, $p3m1_tile_part_flip);
$p3m1_tile_row = $q->Append(stack=>'false'); #$p3m1_tile_row->Write(filename=>'p3m1_p6m_tile_row.jpg', compression=>'JPEG', quality=>'95');
# GENERATE p3m1_tile_row_flip (!!!!!p3m1 is right!!!!!)
$p3m1_tile_row_flip = $p3m1_tile_row->Clone();
$p3m1_tile_row_flip->Flip(); #$p3m1_tile_row_flip->Write(filename=>'p3m1_p6m_tile_row_flip.jpg', compression=>'JPEG', quality=>'95');
# GENERATE p6m_tile
@$q = ();
$q = $p3m1_tile_row->Clone();
push(@$q, $p3m1_tile_row_flip);
$p6m_tile = $q->Append(stack=>'true'); #$p6m_tile->Write(filename=>"$output_folder_path/p6m_$t _$resultimage_name", compression=>'JPEG', quality=>'95');
@$layer = ();
$layer = $p6m_tile->Clone();
# OPTIONAL WRITING OF TILES
#if ($write_tiles == 1) {$p6m_tile->Write(filename=>"$output_folder_path/p6m_$t _$resultimage_name", compression=>'JPEG', quality=>"$jpg_output_quality")};
# EMPTY IMAGE OBJECTS RELATED TO SUBPROGRAM
@$p6m_mask = (); @$image_p6m = (); @$p6m_G1 = (); @$p3m1_G4 = (); @$p3m1_G1 = (); @$p3m1_G2 = ();
@$p3m1_G5 = (); @$p3m1_G5h = (); @$p3m1_G6 = (); @$p3m1_G6h = (); @$transparent_extention = (); @$p3m1_tile_part = ();
@$p3m1_tile_part_flip = (); @$p3m1_tile_row = (); @$p3m1_tile_row_flip = (); @$p6m_tile = ();
# RROGRAM ****************************************************************************************************
return($layer);
};