JavaScript XPM image loading script
スラドの、この記事で:
テーブルアートなるものが紹介されていました:
Gimpを使えばHTML表を吐き出せ、そこで上記ページにあるようにセルなどを設定すれば、HTMLでイメージをかけたりするのですが、ファイルサイズはものすごくでかくなります。
そこでテキスト(Cソース)であるXPM形式にしておき、それをJavaScriptで読み込んで解析し、上記テーブルへ展開するスクリプトを書いてみました。
xpmloader.js
function loadXpm(url) { document.write("<div id='" + url + "'></div>"); loadXpmAt(url, url); } function loadXpmAt(url, parentId) { var xmlhttp = createXmlHttp(); xmlhttp.open("GET", url, true); xmlhttp.onreadystatechange = function () { handleResponse(xmlhttp, parentId); }; xmlhttp.send(null); } function createXmlHttp(){ if (window.ActiveXObject) { return new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { return new XMLHttpRequest(); } else { return null; } } function handleResponse(xmlhttp, parentId) { if (xmlhttp.readyState == 4) { if (xmlhttp.status == 200) { writeXpm(parentId, xmlhttp.responseText); //dumpError(parentId, xmlhttp.responseText); } } } function writeXpm(parentId, source) { var src = source; var infoLinePattern = new RegExp('"([^"]+)"'); var width = 0; var height = 0; var colorNum = 0; var colorSize = 0; if (src.match(infoLinePattern)) { var line = RegExp.lastParen; src = RegExp.rightContext; var nums = line.split(" "); width = parseInt(nums[0]); height = parseInt(nums[1]); colorNum = parseInt(nums[2]); colorSize = parseInt(nums[3]); } else { dumpError(parentId, "Could not read metadata line"); return; } var colors = new Array(colorNum); var colorNo = 0; while (colorNo < colorNum) { if (src.match(infoLinePattern)) { var line = RegExp.lastParen; src = RegExp.rightContext; var colorId = line.substring(0, colorSize); var color = line.substring(colorSize + 1 + 2); colors[colorId] = color; colorNo += 1; } else { dumpError(parentId, "Could not read color line"); return; } } var lineNo = 0; var imageRoot = createImageRoot(); document.getElementById(parentId).appendChild(imageRoot); while (lineNo < height) { if (src.match(infoLinePattern)) { var line = RegExp.lastParen; src = RegExp.rightContext; var imageLine = addImageLine(imageRoot); for (var i = 0; i < width; i++) { var colorId = line.substring(i * colorSize, (i + 1) * colorSize); var color = colors[colorId]; addImageCell(imageLine, color); } lineNo += 1; } else { dumpError(parentId, "Could not read data line"); return; } } } function dumpError(parentId, message) { var textNode = document.createTextNode(message); document.getElementById(parentId).appendChild(textNode); } function createImageRoot() { var table = document.createElement("TABLE"); table.border = "0"; table.cellPadding = "0"; table.cellSpacing = "0"; return table; } function addImageLine(imageRoot) { var tr = imageRoot.insertRow(imageRoot.rows.length); return tr; } function addImageCell(imageLine, color) { var cell = imageLine.insertCell(imageLine.cells.length); cell.bgColor = color; var table = document.createElement("TABLE"); table.border = "0"; table.cellPadding = "0"; table.cellSpacing = "0"; var tr = table.insertRow(table.rows.length); var td = tr.insertCell(tr.cells.length); td.width = "1"; td.height = "1"; cell.appendChild(table); return cell; }
XmlHttpRequestを使っているので、動かすにはHTMLとXPMファイルはWebサーバ上におく必要があると思います。読み込む側のHTMLは以下のような感じです:
<html> <body> <script src="xpmloader.js"> </script> <script language="JavaScript"> loadXpm("test.xpm"); </script> </body> </html>
こんな感じでいけます。loadXpmはこの位置に埋め込みますが、loadXpmAt(url, parentId)を使えば、任意の要素の下に置けます。
とても重たいです。100x100だと固まったようになります。表示完了時間はIE6よりfirefoxのほうが早く終わると感じました。
おまけxpm
/* XPM */ static char * test2_xpm[] = { "32 32 227 2", " c #FFFFFF", ". c #F5F5F5", "+ c #D1D1D1", "@ c #A5A5A5", "# c #818181", "$ c #696969", "% c #616161", "& c #5E5E5E", "* c #606060", "= c #5F5F5F", "- c #646464", "; c #6C6C6C", "> c #767676", ", c #8D8D8D", "' c #AEAEAE", ") c #D6D6D6", "! c #F6F6F6", "~ c #EBEBEB", "{ c #A7A7A7", "] c #5B5B5B", "^ c #2C2C2C", "/ c #1C1C1C", "( c #1D1D1D", "_ c #202020", ": c #222222", "< c #252525", "[ c #272727", "} c #292929", "| c #2B2B2B", "1 c #2E2E2E", "2 c #303030", "3 c #393939", "4 c #565656", "5 c #979797", "6 c #E5E5E5", "7 c #9D9D9D", "8 c #171717", "9 c #1A1A1A", "0 c #2D2D2D", "a c #2F2F2F", "b c #313131", "c c #323232", "d c #3B3B3B", "e c #B7B7B7", "f c #353535", "g c #161616", "h c #191919", "i c #1E1E1E", "j c #242424", "k c #262626", "l c #282828", "m c #333333", "n c #3C3C3C", "o c #989898", "p c #EFEFEF", "q c #5D5D5D", "r c #1B1B1B", "s c #212121", "t c #373737", "u c #383838", "v c #585858", "w c #D7D7D7", "x c #C0C0C0", "y c #2A2A2A", "z c #363636", "A c #3D3D3D", "B c #B0B0B0", "C c #959595", "D c #2B2125", "E c #4D2133", "F c #711D3F", "G c #861C46", "H c #891F4A", "I c #7B2648", "J c #5B2F41", "K c #42383C", "L c #3E3E3E", "M c #3A3A3A", "N c #919191", "O c #727272", "P c #141414", "Q c #151515", "R c #331F27", "S c #6E1A3C", "T c #AF1452", "U c #D40F5E", "V c #E70D64", "W c #E70D65", "X c #D61160", "Y c #B61B59", "Z c #802B4D", "` c #4D3A41", " . c #7C7C7C", ".. c #131313", "+. c #251B1F", "@. c #6C1739", "#. c #CC105B", "$. c #EC0C66", "%. c #EC0D66", "&. c #EC0D67", "*. c #D01560", "=. c #812D4F", "-. c #494044", ";. c #424242", ">. c #414141", ",. c #404040", "'. c #757575", "). c #626262", "!. c #111111", "~. c #431729", "{. c #AE1150", "]. c #EC0F68", "^. c #EC1068", "/. c #EC1169", "(. c #BA1D5B", "_. c #64384A", ":. c #434343", "<. c #7B7B7B", "[. c #691336", "}. c #DA0F61", "|. c #EC136A", "1. c #EC146A", "2. c #EC126A", "3. c #DD1364", "4. c #863052", "5. c #464646", "6. c #454545", "7. c #444444", "8. c #747474", "9. c #A1A1A1", "0. c #232323", "a. c #0F0F0F", "b. c #151213", "c. c #9E124A", "d. c #EC156B", "e. c #ED186D", "f. c #ED196E", "g. c #ED166C", "h. c #ED156B", "i. c #EC1269", "j. c #EA1068", "k. c #A12959", "l. c #494949", "m. c #484848", "n. c #474747", "o. c #CFCFCF", "p. c #545454", "q. c #0C0C0C", "r. c #271019", "s. c #801741", "t. c #E31D6C", "u. c #ED1E71", "v. c #ED1C70", "w. c #ED1B6F", "x. c #ED1A6E", "y. c #EB1168", "z. c #B3235D", "A. c #787878", "B. c #F4F4F4", "C. c #A3A3A3", "D. c #401B2A", "E. c #A21950", "F. c #E41F6E", "G. c #EE2173", "H. c #EE2072", "I. c #EE1F72", "J. c #ED1D71", "K. c #ED176C", "L. c #EB126A", "M. c #B5235E", "N. c #797979", "O. c #EAD9E0", "P. c #CF417A", "Q. c #ED1B70", "R. c #ED196D", "S. c #A9275C", "T. c #7F7F7F", "U. c #F8A9C9", "V. c #E81569", "W. c #913057", "X. c #4A4A4A", "Y. c #888888", "Z. c #F25896", "`. c #DA1A67", " + c #743A51", ".+ c #4B4B4B", "++ c #9C9C9C", "@+ c #EF2C7A", "#+ c #EC176B", "$+ c #BA2560", "%+ c #54454B", "&+ c #595959", "*+ c #B9B9B9", "=+ c #D71D67", "-+ c #7B3953", ";+ c #DBDBDB", ">+ c #E31F6D", ",+ c #8E3457", "'+ c #50474B", ")+ c #666666", "!+ c #BABABA", "~+ c #F7F7F7", "{+ c #ED1F72", "]+ c #ED3780", "^+ c #CF779A", "/+ c #8A787F", "(+ c #4D4D4D", "_+ c #FEEDF3", ":+ c #F46AA1", "<+ c #EE2978", "[+ c #F25D99", "}+ c #F9B9D2", "|+ c #F7EDF1", "1+ c #A9A9A9", "2+ c #FCDAE7", "3+ c #F57DAD", "4+ c #F14C8E", "5+ c #EF2B79", "6+ c #EE2777", "7+ c #F03781", "8+ c #F25694", "9+ c #F8A8C8", "0+ c #FEF0F5", "a+ c #FEECF3", "b+ c #FABBD4", "c+ c #F79BC0", "d+ c #F690B9", " ", " ", " ", " ", " . + @ # $ % & * = - - ; > , ' ) ! ", " ~ { ] ^ / ( _ : < [ } | 1 2 2 3 4 5 6 ", " . 7 2 8 9 / _ : < [ } 0 a 2 b c c b d # 6 ", " e f g h / i : j k l | a b c m m m m c n o ! ", " p q 8 8 r / s : < [ } 0 2 m f t u u t f m v w ", " x a g 8 / / : : k [ y a m z u u u u u u z A B ", " C h g 8 / / : D E F G H I J K A L L A M u t N ", " O P Q 8 r / R S T U V W X Y Z ` L L L L n 3 . ", " * ..P g h +.@.#.$.%.&.&.%.$.*.=.-.;.>.,.L n '. ", " ).!...Q 8 ~.{.&.].^././.^.].&.(._.:.:.;.>.L O ", " <.!.!...P [.}./.|.1.1.|.2./.^.3.4.5.6.7.:.>.8. ", " 9.0.a.!.b.c.d.e.f.f.e.g.h.|.i.j.k.l.m.n.6.:.8. ", " o.p.q.r.s.t.u.u.u.v.w.x.e.g.|.y.z.l.l.l.m.6.A. ", " B.C.D.E.F.G.G.G.H.I.J.v.x.K.h.L.M.l.l.l.l.n.N. ", " O.P.G.G.G.G.G.G.G.I.v.Q.R.g.|.S.l.l.l.l.l.T. ", " U.G.G.G.G.G.G.G.G.G.u.v.x.K.V.W.l.l.l.l.X.Y. ", " Z.G.G.G.G.G.G.G.G.G.H.v.w.K.`. +l.l.l.l..+++ ", " @+G.G.G.G.G.G.G.G.G.G.v.w.#+$+%+l.l.l.l.&+*+ ", " @+G.G.G.G.G.G.G.G.G.G.v.x.=+-+l.l.l.l.l.T.;+ ", " Z.G.G.G.G.G.G.G.G.G.H.Q.>+,+'+l.l.l.l.)+!+~+ ", " U.G.G.G.G.G.G.G.G.G.{+]+^+/+= (+(+= # !+p ", " _+:+G.G.G.G.G.G.G.<+[+}+|+;+!+1+1+!+;+~+ ", " 2+3+4+5+G.6+7+8+9+0+ ", " a+b+c+d+c+b+a+ ", " ", " ", " ", " "};