#!/usr/
Local/bin/pike
// pic2html v0.
4 - converts images into HTML text
// Author: Patrik Roos
( patrik@text-image.com )// Language: Pike
7.
6 ( http://pike.ida.liu.se/ )// VARIABLES
// Initialize variables
Int timestart =
Time(); // Check when script started
Int textType_count = -
1; // Start at the beginning
String textType =
"sequence"; // Default
To sequence
array HTMLcharacter =
({ "0",
"1" }); // Default
To 0
's and 1'sString bgColor =
"black"; // Default
To black background
int|string fontSize = -
3; // Default
To font size -
3Int grayscale =
0; // Default
To colour
String browser =
"ie"; // Default
To Internet Explorer
// Some more strings that will be used
String imageURL;
String HTMLheader, beginHTML, endHTML, fontHTMLstart, fontHTMLend;
// FUNCTIONS
//
Function To decide what the HTML page should look like
void setHTMLvars
() { HTMLheader =
"<!-- Generated on " + __DATE__ +
" using pic2html.cgi, by Patrik Roos -->\n\n";
beginHTML =
"<HTML><HEAD><TITLE>Text image</TITLE></HEAD><BODY>\n";
endHTML =
"</td></tr></table>\n</BODY></HTML>";
fontHTMLstart =
"<font color=";
fontHTMLend =
"</font>";
}//
Function To Write an HTML
Error page
void werr
(String errorMessage
) { setHTMLvars
();
Write(HTMLheader +
"\n" + beginHTML +
"\n");
Write("<table align=center><tr bgcolor=black><td><font color=lightblue size=4>Error: " + errorMessage +
"</font></td></tr></table>\n");
Write(endHTML +
"\n");
Return;
}//
Function To choose
Next character
For OutputString nextCharacter
() { If (sizeof
(HTMLcharacter
) ==
1) { Return HTMLcharacter
[0];
} If (textType ==
"random") { Return HTMLcharacter
[Random(sizeof
(HTMLcharacter
))];
} Else If (textType ==
"sequence") { textType_count++;
If (textType_count >= sizeof
(HTMLcharacter
)) { textType_count =
0;
Return HTMLcharacter
[0];
} Return HTMLcharacter
[textType_count
];
}}// Main program
Int main
(Int argc, array
(String) argv
) { Write("Content-Type: text/html\r\n\r\n"); // Start outputting HTML
Int imageWidth =
130; // Default
To 130 characters wide
// Make sure user posted
Data And that it
's not too large Int temp =
(Int)getenv
("CONTENT_LENGTH");
If (!temp
) { werr
("No image specified.");
Return 0;
} If (temp >
10485760) { werr
("Image too large (10MB limit).");
Return 0;
} //
Read posted
Data from user
String info = Stdio.stdin.read
(temp
);
If (strlen
(info
) < temp
) { werr
("Insufficient data uploaded.");
Return 0;
} // Record the headers used
mapping
(String:string
) headies =
([ ]);
headies
["content-type"] = getenv
("CONTENT_TYPE");
headies
["content-length"] = getenv
("CONTENT_LENGTH");
String imageData;
//
Put the
Data into strings
To see what settings the user chose
object msg = MIME.Message
( info, headies
);
foreach
(msg->body_parts, object food
) { switch
(food->disp_params->name
) { Case "image":
imageURL = food->get_filename
();
imageData = food->getdata
();
break;
Case "textType":
textType = food->getdata
();
break;
Case "width":
imageWidth =
(Int)(food->getdata
());
break;
Case "characters":
HTMLcharacter = food->getdata
() /
"";
break;
Case "bgcolor":
bgColor = food->getdata
();
break;
Case "fontsize":
fontSize = food->getdata
();
break;
Case "grayscale":
grayscale =
(Int)(food->getdata
());
break;
Case "browser":
browser = food->getdata
();
break;
default:
break;
} } // Now set the HTML layout
setHTMLvars
();
// Check
If there
's been an image submitted, and exit if there hasn't If (!imageURL
) { imageURL =
"Error";
werr
("Must specify image.");
Return 0;
} // Check
If Width Is within limits,
And force
To 100 If Not If (imageWidth <
1 || imageWidth >
500) { imageWidth =
100;
} // Create image from
Data Image.Image image;
mixed imageerror = catch
{ image = Image.ANY.decode
(imageData
);
};
// Check
If there
's been an error creating the image, exit if there has If (!image || imageerror
) { werr
("Failed to get image.");
Return 0;
} If (grayscale
) image = image->grey
();
image = image->scale
(imageWidth,
0); // Resize
To fit chosen
Width If (browser ==
"ie") image = image->scale
(1.
0,
0.
65); //
Fix aspect ratio
(Internet Explorer
) Else image = image->scale
(1.
0,
0.
43); //
Fix aspect ratio
(Firefox
) Int Width = image->xsize
();
Int height = image->ysize
();
If (Width >
2000 || height >
2000) { werror
("Image size too large.");
Return 0;
} // Start outputting the HTML page
If (HTMLheader
) { Write(HTMLheader
);
} Write(beginHTML
);
Write("<table align=\"center\
" cellpadding=\"10\
">\n<tr bgcolor=\"" + bgColor + "\
"><td>\n\n<!-- IMAGE BEGINS HERE -->\n<font size=\"" + fontSize + "\
">\n<pre>");
array
(Int) colours;
array
(Int) oldcolours =
({ -
1 }); // Set impossible value
For previous colours
// Now
For the fun stuff:
// First we make some loops that will go through each
Line, one by one.
// The inner
Loop will
Read each pixel
's colour and then output the corresponding HTML coloured character // It also checks
If the last character had the same colour,
And If so doesn
't output the same colour codes // again, thus saving a few bytes.
// The outer
Loop should explain itself.
For (Int y =
0; y < height; y++
) { For (Int x =
0; x <
Width; x++
) { colours = image->getpixel
(x,y
);
If (!equal
(colours,oldcolours
)) { Image.Color.Color colour = Image.Color.rgb
(colours
[0],colours
[1],colours
[2]);
If (x ==
0) Write(fontHTMLstart + colour->html
() +
">" + nextCharacter
());
Else Write(fontHTMLend + fontHTMLstart + colour->html
() +
">" + nextCharacter
());
} Else { Write(nextCharacter
());
} oldcolours = colours;
} oldcolours =
({ -
1 });
Write(fontHTMLend +
"<br>");
} // We
're done! Finish up the HTML page, and tell the user how long it took Write("\n</pre></font>");
Write("\n<!-- IMAGE ENDS HERE -->\n");
Write("\n<P><FONT COLOR=LIGHTBLUE SIZE=2>Rendering time: " +
(Int)round
(Time(timestart
)) +
" seconds.</FONT><BR>\n");
Write(endHTML
);
}