file=io.open(arg[1],"rb") oname=arg[1]:gsub("%.[^%.]+","_output.txt") byte=nil --54 is size of header file:read(18) --Read in the pixel width of the image _width=file:read(4) swidth="" for _w in _width:gmatch(".") do swidth=string.format("%02X",string.byte(_w))..swidth end rowsize=tonumber(swidth,16) --Read the pixel height of the image, including its orientation _height=file:read(4) sheight="" for _h in _height:gmatch(".") do sheight=string.format("%02X",string.byte(_h))..sheight end imgheight=tonumber(sheight,16) --Handle two's complement. Good god this is hacky if imgheight>tonumber("7FFFFFFF",16) then imgheight=imgheight-tonumber("FFFFFFFF",16)-1 end file:read(2) --Read in whether the bitmap is 24 or 32 bit (fuck handling anything less) bitsize=string.byte(file:read(1)) wordsize=bitsize/8 file:read(25) --Pixel size px=tonumber(arg[2]) or 1 --Multiple lines or single line? multi=arg[3] or "true" --Tolerance in rgb-space for standard deviation of average pixel color tolerance=tonumber(arg[4]) or 40 --Alpha channel? alpha=false afile=nil if arg[5]~=nil then alpha=true afile=io.open(arg[5],"rb") afile:read(54) end --Distance in rgb space local function cdist(r1,g1,b1,r2,g2,b2) return math.sqrt((r1-r2)^2+(g1-g2)^2+(b1-b2)^2) end counter=0 bytesread=0 --Stores previous color used, standard deviation, last color _r,_g,_b=-1*tolerance-1,-1*tolerance-1,-1*tolerance-1 sr,sg,sb=_r,_g,_b lr,lg,lb=_r,_g,_b --Stores current and previous alphas aval="00" praval="00" ppraval="00" --Width of next shape to draw width=1 --String to store each line line="" --Table to store processed image imgtable={} print("\nProcessing "..arg[1].." with "..px.."x"..px.." pixels at tolerance "..tolerance..".") if multi=="true" then print("Each row will be output on a new line.") else print("The entire image will be output as one line.") end --For progress reporting print("\n"..("_"):rep(20).."/100%") progstep=math.floor(math.abs(imgheight)/20) --Force alpha tag if alpha channel is on if alpha then ppraval="GG" end while true do byte=file:read(wordsize) bytesread=bytesread+wordsize if byte==nil then break end b,g,r=byte:match("^(.)(.)(.)") if b==nil or g==nil or r==nil then break end r=string.byte(r) g=string.byte(g) b=string.byte(b) --Temporary old values of the average _tr,_tg,_tb=_r,_g,_b if _r>=0 then --Keep a running average of the rgb values _r=_r+(r-_r)/(width+1) _g=_g+(g-_g)/(width+1) _b=_b+(b-_b)/(width+1) --Keep a running standard deviation or the rbg values sr=sr+(r-_tr)*(r-_r) sg=sg+(g-_tg)*(g-_g) sb=sb+(b-_tb)*(b-_b) end --Read and average alpha channel if alpha then abyte=afile:read(wordsize) ab,ag,ar=abyte:match("^(.)(.)(.)") aval=string.format("%02X", math.floor((string.byte(ab)+string.byte(ag)+string.byte(ar))/3)) end if ((cdist(lr,lg,lb,r,g,b)=0 then shape=string.format("m 0 0 l 0 %d %d %d %d 0",px,width*px,px,width*px) --Add color code code=string.format("%02X%02X%02X",_tb,_tg,_tr) if praval~=ppraval then line=line.."{\\c&H"..code.."&\\alpha&H"..praval.."&}" else line=line.."{\\c&H"..code.."&}" end line=line..shape end --Reset width and colors width=1 _r,_g,_b=r,g,b sr,sg,sb=0,0,0 --Set last alpha value if alpha then ppraval=praval praval=aval end end --Set last r,g,b values lr,lg,lb=r,g,b counter=counter+1 if counter%rowsize==0 then --Read filler bytes file:read(math.abs((4-bytesread)%4)) if alpha then afile:read(math.abs((4-bytesread)%4)) end bytesread=0 --Dump current shape on end of line code=string.format("%02X%02X%02X",_b,_g,_r) shape=string.format("m 0 0 l 0 %d %d %d %d 0",px,width*px,px,width*px) if alpha then line=line.."{\\c&H"..code.."&\\alpha&H"..aval.."&}" else line=line.."{\\c&H"..code.."&}" end line=line..shape --Add line to table table.insert(imgtable,line) --Progress report rprog=math.floor(counter/rowsize) if rprog%progstep==0 or rprog==math.abs(imgheight) then io.write("|") end --Reset the line line="" --Reset previous colors _r=-1*tolerance-1 _g=-1*tolerance-1 _b=-1*tolerance-1 sr,sg,sb=_r,_g,_b lr,lg,lb=_r,_g,_b --Reset alpha if alpha channel is on if alpha then praval="GG" end --Reset width width=1 end end --Close files file:close() if alpha then afile:close() end --Open output file output=io.open(oname,"wb") --Set proper prefixes and eol prefix=function() return "{\\p1}" end eol="{\\p0}\\N" if multi=="true" then prefix=function(h) return string.format("{\\p1\\an7\\pos(0,%d)}",h) end eol="\r\n" end --Write the rows in the correct order rstart,rend,step=#imgtable,1,-1 if imgheight<0 then rstart,rend,step=1,#imgtable,1 end count=0 for i=rstart,rend,step do output:write(prefix(count*px)..imgtable[i]) if i~=rend then output:write(eol) end count=count+1 end output:close() io.write("\n")--just for prettiness