CRMT-bitmap-image-interpreter
Given:
- a folder with prototile shapes: png images with monochrome shapes on transparent background with no boarders: $prototile_folder_path
- a text file with a CRMT command list: $CRMT_string_path
- example: p3m1 CRMT command list: C0, x0, y0, C0, Fo, R-60, x-1/2*t_w, y0, C0, Fo, R60, x1/2*t_w, y0, C0, Fo, R-60, Fi, xt_w, y0, C0, Fi, x3/2*t_w, y0, C0, Fo, R60, Fi, x2*t_w, y0, C0, Fo, R-60, x5/2*t_w, y0, C0, Fi, x0, yt_h, C0, Fo, R-60, Fi, x-1/2*t_w, yt_h, C0, Fo, R60, Fi, x1/2*t_w, yt_h, C0, Fo, R-60, xt_w, yt_h, C0, x3/2*t_w, yt_h, C0, Fo, R60, x2*t_w, yt_h, C0, Fo, R-60, Fi, x5/2*t_w, yt_h
The basic ideas is to read the CRMT string, split it into a global list with one CRMT command each and process all the local lists that start with "C" (and end with "y" + something). The x- and y-values can be integers or like in the p3m1-example a variable that codes the width (t_w) and height (t_h) of the one prototile.
The following code is the main part of the image interpreter without the first part that defines the parameters and last part that defines the subprograms.
###MAIN START ########################################################################################################################################################### # READ PROTOTILE/S FROM $prototile_folder_path IN IMAGE OBJECT $Shape_list if ($read_prototile == 1) { print "read sorted png prototile/s from $prototile_folder_path in Shape_list\n"; & read_prototiles; # @_ = ($prototile_folder_path); return($Shape_list); }; $nr_Shape_list = @$Shape_list; print "check nr of elements in Shape_list: nr_Shape_list = $nr_Shape_list\n\n";
# CRMT COMMAND LIST STRING => LIST # READ TEXT FILE $CRMT_string_path IN STRING $CRMT_string open (FILEHANDLE,"<$CRMT_string_path"); my $CRMT_string_global = do { local $/; <FILEHANDLE> }; print "read CRMT_string_global: $CRMT_string_path = $CRMT_string_global \n\n";
# SPLIT $CRMT_string_global IN PARTS SEPARATED BY /, / AND PUSH THE PARTS IN LIST @CRMT_list_global @CRMT_list_global = split(/, /, $CRMT_string_global); print "split string in list: CRMT_list_global = @CRMT_list_global\n"; $nr_CRMT_list_global = @CRMT_list_global; print "nr list elements: nr_CRMT_list_global = $nr_CRMT_list_global\n";
# GET SUB-LIST-STARTPOSITIONS AND NR OF SUB-LISTS IN @CRMT_list_global & get_sublist_startpositions; # @_ = (@CRMT_list_global); return(@sublist_startposition); $nr_sublists = @sublist_startposition; print "nr of sublists in CRMT_list_global: nr_sublists = $nr_sublists\n";
# COMPUTE tile_w AND tile_h & get_tile_wh; # @_ = ($Shape_list, $mult_w, $mult_h); return($tile_w, $tile_h);
for ($q = $composing_number_min; $q <= $composing_number_max; $q++) { my $time_1 = time;
# CLONE GLOBAL LIST @CRMT_list_global @CRMT_list_global_clone = @CRMT_list_global; #print "clone CRMT_list_global: CRMT_list_global_clone = @CRMT_list_global_clone\n\n";
# DEFINE OBJECT $tile FOR EVERY ITERATION => undef $tile AT END OF EVERY ITERATION $tile = new Image::Magick; $tile->Set(size=>"$tile_w x $tile_h"); print "generate empty tile with tile_w x tile_h = $tile_w x $tile_h \n"; $tile->Read('xc:none'); #$tile->Write(filename=>"$output_meta_folder/tile_AfterGeneration.png");
# PROCESS THE COMMAND ELEMENTS IN EVERY SUBLIST for ($i = 1; $i <= $nr_sublists; $i++) {
print "\n !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! processing CRMT_list $i from $nr_sublists !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \n\n";
# SEPERATE FIRST LOCAL COMMAND LIST @CRMT_list_local_1 # DETERMINE POSITION OF SECOND C if ($i < $nr_sublists) { for ($j = 1; $j <= @CRMT_list_global_clone-1; $j++) { if ($CRMT_list_global_clone[$j] =~ /^C/) { $split_position = $j; print "first split_position = $split_position\n"; last; }; }; } else {$split_position = @CRMT_list_global_clone; print "first split_position = $split_position\n"};
# COPY FIRST $split_position-1 POSITIONS FROM @CRMT_list_global_clone IN @CRMT_list_local_1 for ($j = 0; $j <= $split_position-1; $j++) { push(@CRMT_list_local, $CRMT_list_global_clone[$j]) }; print "copy first $split_position elements in local list: CRMT_list_local = @CRMT_list_local\n\n";
# DELETE FIRST $split_position-1 POSITIONS FROM @CRMT_list_global_clone splice(@CRMT_list_global_clone, 0, $split_position, ()); print "CRMT_list_global_clone after splice(first $split_position) = @CRMT_list_global_clone\n"; $nr_CRMT_list_global_clone = @CRMT_list_global_clone; print "nr_CRMT_list_global_clone after splice(first $split_position) = $nr_CRMT_list_global_clone\n"; $nr_CRMT_list_local = @CRMT_list_local; print "nr_CRMT_list_local = $nr_CRMT_list_local \n";
# GET COMMANDS AND COMMAND PARAMETERS FROM @CRMT_list_local AND MAKE IMAGE PROCESSING while ($nr_CRMT_list_local >= 0) {
if ($CRMT_list_local[0] =~ /^C/) { $shape_value = substr($CRMT_list_local[0], 1, length($CRMT_list_local[0])); print "list element $CRMT_list_local[0]: shape_value = $shape_value \n"; @$prototile_crm = (); $prototile_crm = $Shape_list->[$shape_value]->Clone();#$prototile_crm->Write(filename=>"$output_meta_folder/prototile_crm_AfterGeneration.png"); };
if ($CRMT_list_local[0] =~ /^R/) { $rotate_value = substr($CRMT_list_local[0], 1, length($CRMT_list_local[0])); print "list element $CRMT_list_local[0]: rotate_value = $rotate_value \n"; $prototile_crm->Rotate(degrees=>"$rotate_value", color=>'transparent'); $prototile_crm->Set(page=>'0x0+0+0'); #$prototile_crm->Write(filename=>"$output_meta_folder/prototile_crm_AfterRot.png"); $prototile_crm->Trim(); #$prototile_crm->Write(filename=>"$output_meta_folder/prototile_crm_AfterTrim.png"); };
if ($CRMT_list_local[0] =~ /^Fo/) { print "list element $CRMT_list_local[0]: make Flop \n"; $prototile_crm->Flop(); #$prototile_crm->Write(filename=>"$output_meta_folder/prototile_crm_AfterFlop.png"); };
if ($CRMT_list_local[0] =~ /^Fi/) { print "list element $CRMT_list_local[0]: make Flip \n"; $prototile_crm->Flip(); #$prototile_crm->Write(filename=>"$output_meta_folder/prototile_crm_AfterFlip.png"); };
if ($CRMT_list_local[0] =~ /^x/ and $CRMT_list_local[1] =~ /^y/) { print "list element $CRMT_list_local[0]: make translation with \n"; $x_string = substr($CRMT_list_local[0], 1, length($CRMT_list_local[0])); print "x_string = $x_string \n"; $y_string = substr($CRMT_list_local[1], 1, length($CRMT_list_local[1])); print "y_string = $y_string \n"; if (looks_like_number($x_string)) { $x_value = $x_string; print "x_string = $x_string looks_like_number => use x_string as x_value \n"; } else { $x_string =~ s/t/$dollar_sign_t/g; print "change t by dollar+t in x_string = $x_string\n"; $x_value = eval $x_string; print "direct eval x_string: x_value = $x_value\n"; }; if (looks_like_number($y_string)) { $y_value = $y_string; print "y_string = $y_string looks_like_number => use y_string as y_value \n"; } else { $y_string =~ s/t/$dollar_sign_t/g; print "change t by dollar+t in y_string = $y_string\n"; $y_value = eval $y_string; print "direct eval y_string: y_value = $y_value\n"; }; print "make compose=>'over' with translation: x_value = $x_value and y_value = $y_value \n"; $tile->Composite(image=>$prototile_crm, compose=>'over', x=>"$x_value", y=>"$y_value", color=>'transparent', matte=>'true'); $tile->Set(page=>'0x0+0+0'); #$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_$i.png"); splice(@CRMT_list_local, 0, 2, ()); print "splice first two elements => CRMT_list_local = ( @CRMT_list_local ) => End of processing $i 'th CRMT_list_local\n"; last; }; #if ($CRMT_list_local[0] =~ /^x/ and $CRMT_list_local[1] =~ /^y/)
# DELETE FIRST ELEMENT FROM @CRMT_list_local if ($CRMT_list_local[0] =~ /^C/ or $CRMT_list_local[0] =~ /^R/ or $CRMT_list_local[0] =~ /^Fo/ or $CRMT_list_local[0] =~ /^Fi/) { splice(@CRMT_list_local, 0, 1, ()); print "splice first element => CRMT_list_local_$i = ( @CRMT_list_local ) \n"; }; $nr_CRMT_list_local = @CRMT_list_local; print "nr_CRMT_list_local = $nr_CRMT_list_local \n"; }; #while ($nr_CRMT_list_local >= 0) }; # for ($i = 1; $i <= $nr_sublists; $i++) {
# CORRECTION OF LINE ARTEFACTS (DIAGONAL AND HORIZONTAL) & process_artefacts_1; # @_ = ($tile, $q); # return($tile);
# WRITE $tile & make_result_path_CRMT; # @_ = ($output_meta_folder, $resultimage_template, $index_for_result, $q, $make_result_folder, $output_folder_path); # return($result_path); $tile->Write(filename=>"$result_path", compression=>'JPEG', quality=>"$jpg_output_quality"); # quality=>'98'
# UNDEFINE & EMPTY OBJECTS undef $tile; #@$tile = ();
$time_2 = time; my $deltatime = $time_2 - $time_1; push(@deltatime_list1, $deltatime); }; # for ($q = $composing_number_min; $q <= $composing_number_max; $q++)
###MAIN END #############################################################################################################################################################