This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Terminator_NL's profile picture

BetterPaint (Paintutils with text support)

Started by Terminator_NL, 27 February 2015 - 02:51 PM
Terminator_NL #1
Posted 27 February 2015 - 03:51 PM
This program is a replacement for paintutils and the paint program. In one.

Current version: 2
Get it here: Q7AQ1n2Y

PNG converter:
http://puu.sh/gtCf5/5647b88d6f.rar

Features:
  • In - game editor
  • All in one, no other dependencies
  • Converts paintutils format to his own format
  • Image panning (Writing images bigger than the terminal)
  • Painting using text
  • Automated writing without affecting background
  • In-game documentation
  • Write buffer. Gets almost all user input (Mouse dragging)
  • User friendly
API functions:
Drawing an image to the screen
[indent=1]paint.drawImage( <File name> <xPos> <yPos> <redirection object> )[/indent]
Drawing text OVER the last image, not affecting background. (relative to the image position)
[indent=1]paint.overWrite( <Text>, <xPos>, <yPos>,<color> )[/indent]
Converting paintutils format to betterpaint format
[indent=1]paint.import( <Source (paintutils format)>, <Destination (betterpaint format)> )[/indent]

Usage:


[indent=1]paint[/indent]
[indent=2]– Does nothing, allows for loading quietly as api.[/indent]
[indent=1]paint <file name>[/indent]
[indent=2]– Opens or creates a file to paint[/indent]
[indent=1]paint import <source> <destination>[/indent]
[indent=2]– Converts paintutils format to betterpaint format, Source as paintutils file. Destination as betterpaint format.[/indent]

Disclaimer:
For using this program/api in one of your programs you are free to do whatever you want. As long as I get a bit of credit (only if there is a credits section!)
Feedback is always welcome and I'd be happy to improve the program further if desired!







Latest version:
Spoiler

transparentIcon = "-"
args = {...}
tX, tY = term.getSize()

function import(source,dest)
init()
if fs.exists(source) == false then
  print("File "..source.." doesnt exists!")
  error()
elseif not dest then
  print("Provide an output file.")
  error()
elseif fs.exists(dest) == true then
  print("File "..dest.." already exists!")
  error()
end
--if mode == "import" then
  h = fs.open(source,"r")
  lines = {}
  count = 0
  repeat
   count = count + 1
   lines[count] = h.readLine(count)  
  until lines[count] == nil
  h.close()
  data = {}
  if not painted then
   painted = {}
  end
  for i=1,#lines do
   data[i] = {}
   string.gsub(lines[i],".",function(char) table.insert(data[i],char) end)
  end
  x=0
  y=0
  for i=1,#data do
   y = y + 1
   x = 0
   for a=1,#data[i] do
	x = x + 1
	if not painted[x] then
	 painted[x] = {}
	end
	if not painted[x][y] then
	 painted[x][y] = {}
	end
	rawColor = data[i][x]
	if rawColor == "0" then
	 colorLoaded = colors.white
	elseif rawColor == "1" then
	 colorLoaded = colors.orange
	elseif rawColor == "2" then
	 colorLoaded = colors.magenta
	elseif rawColor == "3" then
	 colorLoaded = colors.lightBlue
	elseif rawColor == "4" then
	 colorLoaded = colors.yellow
	elseif rawColor == "5" then
	 colorLoaded = colors.lime
	elseif rawColor == "6" then
	 colorLoaded = colors.pink
	elseif rawColor == "7" then
	 colorLoaded = colors.gray
	elseif rawColor == "8" then
	 colorLoaded = colors.lightGray
	elseif rawColor == "9" then
	 colorLoaded = colors.cyan
	elseif rawColor == "a" then
	 colorLoaded = colors.purple
	elseif rawColor == "b" then
	 colorLoaded = colors.blue
	elseif rawColor == "c" then
	 colorLaoded = colors.brown
	elseif rawColor == "d" then
	 colorLoaded = colors.green
	elseif rawColor == "e" then
	 colorLoaded = colors.red
	elseif rawColor == "f" then
	 colorLoaded = colors.black
	elseif rawColor == " " then
	 -- Do nothing, allow it
	else
	 error("File: \""..source.."\" has an incorrect format!")
	end
	if rawColor ~= " " then
	 painted[x][y] = {colorLoaded," ",colorLoaded}  
	else
	 painted[x][y] = nil
	end
   end
  end
--end
args[1] = dest
save()
end


function drawImage(file,xSet,ySet,redirection)
init()
lastImage = file
lastX = xSet
lastY = ySet
lastRedirection = redirection
if redirection then
  current = term.current()
  term.redirect(redirection)
end
drawData(xSet,ySet,file)
if redirection then
  term.redirect(current)
end
end

function overWrite(textSet,xSet,ySet,colorSet)
init()
exists = true
if not lastImage then
  error("Use drawImage first!")
end
if not writeBuffer then
  writeBuffer = {}
end
if not writeBuffer[lastImage] then
  writeBuffer[lastImage] = {}
end
plusPos = 0
for char in string.gmatch(textSet,".") do
  if not writeBuffer[lastImage][xSet+plusPos] then
   writeBuffer[lastImage][xSet+plusPos] = {}
  end
  if not writeBuffer[lastImage][xSet+plusPos][ySet] then
   writeBuffer[lastImage][xSet+plusPos][ySet] = {colors.black," ",colors.white}
  end
  writeBuffer[lastImage][xSet+plusPos][ySet][2] = char
  writeBuffer[lastImage][xSet+plusPos][ySet][3] = colorSet
  plusPos = plusPos + 1
end
drawImage(lastImage,lastX,lastY,lastRedirection)
end

function init()
function eventHandler()
while true do
  event = {os.pullEvent()}
  if event[1] == "key" then
   if event[2] == keys.leftCtrl or event[2] == 157 then
	menuStatus = not menuStatus
	writeMenuBar(menuStatus)
   end
   if menuStatus == true then
	if event[2] == keys.right or event[2] == keys.left then
	 if menuItemSelected == 1 then
	  menuItemSelected = 2
	 else
	  menuItemSelected = 1
	 end
	 writeMenuBar(menuStatus)
	elseif event[2] == keys.enter then
	 if menuItemSelected == 1 then
	  save()
	  writeMenuBar(false)
	 else
	  term.setTextColor(colors.yellow)
	  term.setBackgroundColor(colors.black)
	  term.clear()
	  term.setCursorPos(1,1)
	  error()
	 end
	end
   else  
	if event[2] == keys.right then
	 drawData(offSetX-1,offSetY)
	 drawMenu()
	 writeMenuBar(menuStatus)
	elseif event[2] == keys.left then
	 drawData(offSetX+1,offSetY)
	 drawMenu()
	 writeMenuBar(menuStatus)
	elseif event[2] == keys.up then
	 drawData(offSetX,offSetY+1)
	 drawMenu()
	 writeMenuBar(menuStatus)
	elseif event[2] == keys.down then
	 drawData(offSetX,offSetY-1)
	 drawMenu()
	 writeMenuBar(menuStatus)
	end
   end
  end
  if event[1] == "mouse_click" or event[1] == "mouse_drag" then
   if event[3] > 2 and event[4] ~= tY then
	insertItem(event[3],event[4],event[2])
   elseif event[4] < 18 and event[4] > 1 then
	if event[3] == 1 then
	 bgSelected = 2^(event[4]-2)
	elseif event[3] == 2 then
	 tSelected = 2^(event[4]-2)
	end
	drawMenu()
   elseif event[4] == tY - 1 and event[3] == 1 then
	setLetter()
	drawData(offSetX,offSetY)
	drawMenu()
   elseif event[3] == tX and event[4] == tY and menuStatus == false then
	writeHelp()
   end
  end
  if event[1] == "char" then
   textSelected = string.sub(event[2],1,1)
   drawMenu()
  end
  --drawData(offSetX,offSetY)
end
end

function writeHelp()
term.setBackgroundColor(colors.black)
term.setTextColor(colors.green)
term.clear()
term.setCursorPos(1,1)
term.write("Help:")
term.setTextColor(colors.white)
term.setCursorPos(1,3)
print("Usage:")
term.setTextColor(colors.lightGray)
print("  Select color: Click on the color on the left")
print("  Change draw char: Press a key on the keyboard")
print("  Change transparent icon: Click on the icon's char in the menu")
print("  Change text color: Click on a color in the menu on the right side")
print("  Change background color: Click on a color in the menu on the left side")
term.setTextColor(colors.white)
print()
print("Controls:")
term.setTextColor(colors.lightGray)
print("  Arrow keys to pan")
print("  Left mouse button to select and draw")
print("  Right mouse button to delete")
print("  Ctrl to open menu")
print()
term.setTextColor(colors.white)
term.write("Click a mouse button to exit.")
term.setTextColor(colors.orange)
term.setCursorPos(tX-9,1)
term.write("API help >")
event = {os.pullEvent("mouse_click")}
if event[3] > tX-10 and event[4] == 1 then
  drawAPIhelp()
end
drawData(offSetX,offSetY)
drawMenu()
writeMenuBar(menuStatus)
end

function drawAPIhelp()
term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.orange)
print("API help menu:")
term.setTextColor(colors.white)
print("Drawing an image: ")
term.setTextColor(colors.lightGray)
print(shell.getRunningProgram(),".drawImage(<file name>,<x pos>,<y pos>,[redirection object])")
print()
term.setTextColor(colors.white)
print("Overlaying text on the last image:")
term.setTextColor(colors.lightGray)
print(shell.getRunningProgram(),".overWrite(<Text>,<x pos>,<y pos>,<text color>)")
print()
term.setTextColor(colors.white)
print("Convert an paintutils file to betterpaint file:")
term.setTextColor(colors.lightGray)
print(shell.getRunningProgram(),".import(<source>,<destination>)")
term.setTextColor(colors.red)
print()
print("Overwriting text will only work AFTER drawing an image!")
term.setTextColor(colors.white)
print()
print("Example:")
term.setTextColor(colors.lightGray)
print("os.loadAPI(\"",shell.getRunningProgram(),"\")")
print(shell.getRunningProgram(),".drawImage(\"myPicture\",1,1)")
term.write((shell.getRunningProgram()..".overWrite(\"Hello!\",2,3,colors.orange)"))
os.pullEvent("mouse_click")
end

function setLetter()
term.setBackgroundColor(colors.red)
term.setTextColor(colors.black)
for i=1,4 do
  term.setCursorPos(tX/2-11,(tY/2-4)+i)
  term.write("					 ")
end
term.setCursorPos(tX/2-10,tY/2-2)
term.write("Change transparancy")
term.setCursorPos(tX/2-10,tY/2-1)
term.write("character to: (key)")
event = {os.pullEvent("char")}
transparentIcon = event[2]
end

function insertItem(xPos,yPos,modeSet)
if saved == true then
  saved = false
  writeMenuBar(false)
end
--bgSelected
--tSelected
--textSelected
if not painted then
  painted = {}
end
if not painted[xPos-offSetX] then
  painted[xPos-offSetX] = {}
end
if modeSet == 1 then
   if not textSelected then
	textSelected = " "
   end
   TMPtextSelected = textSelected
   painted[xPos-offSetX][yPos-offSetY] = {bgSelected,textSelected,tSelected}
   term.setBackgroundColor(bgSelected)
   term.setTextColor(tSelected)
  else
   TMPtextSelected = transparentIcon
   term.setBackgroundColor(colors.black)
   term.setTextColor(colors.gray)
   painted[xPos-offSetX][yPos-offSetY] = nil
end
term.setCursorPos(xPos,yPos)
term.write(TMPtextSelected)
end

--if #args ~= 1 then
-- print("Usage: "..shell.getRunningProgram().." <path>")
-- return
--end

if args[1] and fs.exists(args[1]) == true then
buff = fs.open(args[1],"r")
previousData = buff.readAll()
buff.close()
processed = string.sub(previousData,43)
painted = textutils.unserialize(processed)
else
painted = {}
end

function save()
file = fs.open(args[1],"w")
file.write("error('This is an image, not a program!')\n"..textutils.serialize(painted))
file.close()
saved = true
end

function drawData(xStart, yStart, file)
offSetX = xStart
offSetY = yStart
if not file then
  term.setBackgroundColor(colors.black)
  term.setTextColor(colors.gray)
  transparentLine = ""
  for x=1,tX-2 do
   transparentLine = transparentIcon..transparentLine
  end
  for y=1,tY-1 do
   term.setCursorPos(3,y)
   term.write(transparentLine)
  end
else
  if fs.exists(file) == false then
   error("File given doesnt exists! file name: "..file)
  else
   local fileD = fs.open(file,"r")
   raw = fileD.readAll()
   --ignoreL = string.len(fileD.readLine(1))
   processed = string.sub(raw,43)
   --term.redirect(term.native())
  -- textutils.pagedPrint(processed)
   painted = textutils.unserialize(processed)
   fileD.close()
  end
end
if not painted then
  painted = {}
end
paintedF = painted
count = 0
repeat ---------
count = count + 1
for xPos,v in pairs(paintedF) do
  for yPos in pairs (paintedF[xPos]) do
	overWrite = true
	if not lastImage or not writeBuffer or not writeBuffer[lastImage] then
	 overWrite = false
	end
	if overWrite == true then
	 if not writeBuffer[lastImage][xPos] then
	  overWrite = false
	 end
	end
	if overWrite == true then
	 if not writeBuffer[lastImage][xPos][yPos] then
	  overWrite = false
	 end
	end
	if overWrite == false then
	 bgColor = paintedF[xPos][yPos][1]
	 text = paintedF[xPos][yPos][2]
	 tColor = paintedF[xPos][yPos][3]
	else
	 if painted and painted[xPos] and painted[xPos][yPos] and painted[xPos][yPos][1] then
	  bgColor = painted[xPos][yPos][1]
	  else
	  bgColor = colors.black
	 end
	 --if not bgColor then
	--  bgColor = colors.black
	 --end
	 text = writeBuffer[lastImage][xPos][yPos][2]
	 tColor = writeBuffer[lastImage][xPos][yPos][3]
	end
	if not tColor then
	 tColor = colors.white
	end
	if not text then
	 text = " "
	end
	term.setCursorPos(xPos+xStart,yPos+yStart)
	term.setBackgroundColor(bgColor)
	term.setTextColor(tColor)
	term.write(text)
   end
  end
  if count == 1 and writeBuffer and lastImage then
   paintedF = writeBuffer[lastImage]
  elseif count == 1 and not lastImage or not writeBuffer then
   count = 2
  end
until count == 2
term.setCursorPos(1,tY)
end

function drawMenu()
term.setCursorPos(1,1)
term.setTextColor(colors.white)
if not bgSelected then
  bgSelected = colors.black
elseif bgSelected == colors.white then
  term.setTextColor(colors.black)
end
if not tSelected then
  tSelected = colors.white
elseif tSelected == colors.white then
  term.setTextColor(colors.black)
end
if not textSelected then
  textSelected = " "
end
term.setBackgroundColor(bgSelected)
term.write("B")
term.setBackgroundColor(tSelected)
term.write("T")
for i=1,16 do
  i=i-1
  term.setCursorPos(1,i+2)
  term.setBackgroundColor(2^i)
  term.write("  ")
end
term.setCursorPos(1,18)
term.setBackgroundColor(colors.black)
if not textSelected then
  textSelected = " "
elseif string.len(textSelected) > 1 then
  textSelected = string.sub(textSelected,1,1)
end
term.setTextColor(colors.gray)
term.setBackgroundColor(colors.black)
term.write(transparentIcon)
term.setTextColor(tSelected)
term.setBackgroundColor(bgSelected)
term.write(textSelected)
end

function writeMenuBar(booly)
menuStatus = booly
term.setBackgroundColor(colors.black)
if booly == true then
  term.setCursorPos(1,tY)
  term.clearLine()
  if not menuItemSelected then
   menuItemSelected = 1
  end
  term.setTextColor(colors.white)
  term.write(" Save  Exit ")
  term.setCursorPos(6*menuItemSelected-5,tY)
  term.setTextColor(colors.yellow)
  term.write("[")
  term.setCursorPos(6*menuItemSelected,tY)
  term.write("]")
elseif booly == false then
  term.setCursorPos(1,tY)
  term.setTextColor(colors.yellow)
  term.clearLine()
  if saved == true then
   term.write("Saved to "..args[1])
  else
   term.write("Press Ctrl to access menu")
  end
  term.setCursorPos(tX,tY)
  term.setTextColor(colors.lightGray)
  term.write("?")
end
end
end

if args[1] == "import" then -- or args[1] == "export" then
init()
mode = args[1]
source = args[2]
destination = args[3]
if not args[2] then
  print("Usage: "..shell.getRunningProgram().." "..mode.." <source> <destination>")
  error()
end
import(source,destination)
if mode == "import" then
  print("File imported.")
  error()
end
elseif #args > 0 then
init()
menuStatus = false
saved = false
writeMenuBar(menuStatus)
menuItemSelected = 1
drawData(3,0)
drawMenu()
eventHandler()
end




Version 1:
Spoiler

transparentIcon = "-"
args = {...}
tX, tY = term.getSize()
function drawImage(file,xSet,ySet,redirection)
init()
lastImage = file
lastX = xSet
lastY = ySet
lastRedirection = redirection
if redirection then
  current = term.current()
  term.redirect(redirection)
end
drawData(xSet,ySet,file)
if redirection then
  term.redirect(current)
end
end
function overWrite(textSet,xSet,ySet,colorSet)
init()
exists = true
if not lastImage then
  error("Use drawImage first!")
end
if not writeBuffer then
  writeBuffer = {}
end
if not writeBuffer[lastImage] then
  writeBuffer[lastImage] = {}
end
plusPos = 0
for char in string.gmatch(textSet,".") do
  if not writeBuffer[lastImage][xSet+plusPos] then
   writeBuffer[lastImage][xSet+plusPos] = {}
  end
  if not writeBuffer[lastImage][xSet+plusPos][ySet] then
   writeBuffer[lastImage][xSet+plusPos][ySet] = {colors.black," ",colors.white}
  end
  writeBuffer[lastImage][xSet+plusPos][ySet][2] = char
  writeBuffer[lastImage][xSet+plusPos][ySet][3] = colorSet
  plusPos = plusPos + 1
end
drawImage(lastImage,lastX,lastY,lastRedirection)
end
function init()
function eventHandler()
while true do
  event = {os.pullEvent()}
  if event[1] == "key" then
   if event[2] == keys.leftCtrl or event[2] == 157 then
	menuStatus = not menuStatus
	writeMenuBar(menuStatus)
   end
   if menuStatus == true then
	if event[2] == keys.right or event[2] == keys.left then
	 if menuItemSelected == 1 then
	  menuItemSelected = 2
	 else
	  menuItemSelected = 1
	 end
	 writeMenuBar(menuStatus)
	elseif event[2] == keys.enter then
	 if menuItemSelected == 1 then
	  save()
	  writeMenuBar(false)
	 else
	  term.setTextColor(colors.yellow)
	  term.setBackgroundColor(colors.black)
	  term.clear()
	  term.setCursorPos(1,1)
	  error()
	 end
	end
   else  
	if event[2] == keys.right then
	 drawData(offSetX-1,offSetY)
	 drawMenu()
	 writeMenuBar(menuStatus)
	elseif event[2] == keys.left then
	 drawData(offSetX+1,offSetY)
	 drawMenu()
	 writeMenuBar(menuStatus)
	elseif event[2] == keys.up then
	 drawData(offSetX,offSetY+1)
	 drawMenu()
	 writeMenuBar(menuStatus)
	elseif event[2] == keys.down then
	 drawData(offSetX,offSetY-1)
	 drawMenu()
	 writeMenuBar(menuStatus)
	end
   end
  end
  if event[1] == "mouse_click" or event[1] == "mouse_drag" then
   if event[3] > 2 and event[4] ~= tY then
	insertItem(event[3],event[4],event[2])
   elseif event[4] < 18 and event[4] > 1 then
	if event[3] == 1 then
	 bgSelected = 2^(event[4]-2)
	elseif event[3] == 2 then
	 tSelected = 2^(event[4]-2)
	end
	drawMenu()
   elseif event[4] == tY - 1 and event[3] == 1 then
	setLetter()
	drawData(offSetX,offSetY)
	drawMenu()
   elseif event[3] == tX and event[4] == tY and menuStatus == false then
	writeHelp()
   end
  end
  if event[1] == "char" then
   textSelected = string.sub(event[2],1,1)
   drawMenu()
  end
  --drawData(offSetX,offSetY)
end
end
function writeHelp()
term.setBackgroundColor(colors.black)
term.setTextColor(colors.green)
term.clear()
term.setCursorPos(1,1)
term.write("Help:")
term.setTextColor(colors.white)
term.setCursorPos(1,3)
print("Usage:")
term.setTextColor(colors.lightGray)
print("  Select color: Click on the color on the left")
print("  Change draw char: Press a key on the keyboard")
print("  Change transparent icon: Click on the icon's char in the menu")
print("  Change text color: Click on a color in the menu on the right side")
print("  Change background color: Click on a color in the menu on the left side")
term.setTextColor(colors.white)
print()
print("Controls:")
term.setTextColor(colors.lightGray)
print("  Arrow keys to pan")
print("  Left mouse button to select and draw")
print("  Right mouse button to delete")
print("  Ctrl to open menu")
print()
term.setTextColor(colors.white)
term.write("Click a mouse button to exit.")
term.setTextColor(colors.orange)
term.setCursorPos(tX-9,1)
term.write("API help >")
event = {os.pullEvent("mouse_click")}
if event[3] > tX-10 and event[4] == 1 then
  drawAPIhelp()
end
drawData(offSetX,offSetY)
drawMenu()
writeMenuBar(menuStatus)
end
function drawAPIhelp()
term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.orange)
print("API help menu:")
print()
term.setTextColor(colors.white)
print("Drawing an image: ")
term.setTextColor(colors.lightGray)
print(shell.getRunningProgram(),".drawImage(<file name>,<x pos>,<y pos>,[redirection object])")
print()
term.setTextColor(colors.white)
print("Overlaying text on the last image:")
term.setTextColor(colors.lightGray)
print(shell.getRunningProgram(),".overWrite(<Text>,<x pos>,<y pos>,<text color>")
print()
term.setTextColor(colors.red)
print("Overwriting text will only work AFTER drawing an image!")
term.setTextColor(colors.white)
print()
print("Example:")
term.setTextColor(colors.lightGray)
print("os.loadAPI(\"",shell.getRunningProgram(),"\")")
print(shell.getRunningProgram(),".drawImage(\"myPicture\",1,1)")
print(shell.getRunningProgram(),".overWrite(\"Hello!\",2,3,colors.orange)")
os.pullEvent("mouse_click")
end
function setLetter()
term.setBackgroundColor(colors.red)
term.setTextColor(colors.black)
for i=1,4 do
  term.setCursorPos(tX/2-11,(tY/2-4)+i)
  term.write("					 ")
end
term.setCursorPos(tX/2-10,tY/2-2)
term.write("Change transparancy")
term.setCursorPos(tX/2-10,tY/2-1)
term.write("character to: (key)")
event = {os.pullEvent("char")}
transparentIcon = event[2]
end
function insertItem(xPos,yPos,modeSet)
if saved == true then
  saved = false
  writeMenuBar(false)
end
--bgSelected
--tSelected
--textSelected
if not painted then
  painted = {}
end
if not painted[xPos-offSetX] then
  painted[xPos-offSetX] = {}
end
if modeSet == 1 then
   if not textSelected then
	textSelected = " "
   end
   TMPtextSelected = textSelected
   painted[xPos-offSetX][yPos-offSetY] = {bgSelected,textSelected,tSelected}
   term.setBackgroundColor(bgSelected)
   term.setTextColor(tSelected)
  else
   TMPtextSelected = transparentIcon
   term.setBackgroundColor(colors.black)
   term.setTextColor(colors.gray)
   painted[xPos-offSetX][yPos-offSetY] = nil
end
term.setCursorPos(xPos,yPos)
term.write(TMPtextSelected)
end
--if #args ~= 1 then
-- print("Usage: "..shell.getRunningProgram().." <path>")
-- return
--end
if args[1] and fs.exists(args[1]) == true then
buff = fs.open(args[1],"r")
previousData = buff.readAll()
buff.close()
processed = string.sub(previousData,43)
painted = textutils.unserialize(processed)
else
painted = {}
end
function save()
file = fs.open(args[1],"w")
file.write("error('This is an image, not a program!')\n"..textutils.serialize(painted))
file.close()
saved = true
end
function drawData(xStart, yStart, file)
offSetX = xStart
offSetY = yStart
if not file then
  term.setBackgroundColor(colors.black)
  term.setTextColor(colors.gray)
  transparentLine = ""
  for x=1,tX-2 do
   transparentLine = transparentIcon..transparentLine
  end
  for y=1,tY-1 do
   term.setCursorPos(3,y)
   term.write(transparentLine)
  end
else
  if fs.exists(file) == false then
   error("File given doesnt exists! file name: "..file)
  else
   local fileD = fs.open(file,"r")
   raw = fileD.readAll()
   --ignoreL = string.len(fileD.readLine(1))
   processed = string.sub(raw,43)
   --term.redirect(term.native())
  -- textutils.pagedPrint(processed)
   painted = textutils.unserialize(processed)
   fileD.close()
  end
end
if not painted then
  painted = {}
end
paintedF = painted
count = 0
repeat ---------
count = count + 1
for xPos,v in pairs(paintedF) do
  for yPos in pairs (paintedF[xPos]) do
	overWrite = true
	if not lastImage or not writeBuffer or not writeBuffer[lastImage] then
	 overWrite = false
	end
	if overWrite == true then
	 if not writeBuffer[lastImage][xPos] then
	  overWrite = false
	 end
	end
	if overWrite == true then
	 if not writeBuffer[lastImage][xPos][yPos] then
	  overWrite = false
	 end
	end
	if overWrite == false then
	 bgColor = paintedF[xPos][yPos][1]
	 text = paintedF[xPos][yPos][2]
	 tColor = paintedF[xPos][yPos][3]
	else
	 if painted and painted[xPos] and painted[xPos][yPos] and painted[xPos][yPos][1] then
	  bgColor = painted[xPos][yPos][1]
	  else
	  bgColor = colors.black
	 end
	 --if not bgColor then
	--  bgColor = colors.black
	 --end
	 text = writeBuffer[lastImage][xPos][yPos][2]
	 tColor = writeBuffer[lastImage][xPos][yPos][3]
	end
	if not tColor then
	 tColor = colors.white
	end
	if not text then
	 text = " "
	end
	term.setCursorPos(xPos+xStart,yPos+yStart)
	term.setBackgroundColor(bgColor)
	term.setTextColor(tColor)
	term.write(text)
   end
  end
  if count == 1 and writeBuffer and lastImage then
   paintedF = writeBuffer[lastImage]
  elseif count == 1 and not lastImage or not writeBuffer then
   count = 2
  end
until count == 2
term.setCursorPos(1,tY)
end
function drawMenu()
term.setCursorPos(1,1)
term.setTextColor(colors.white)
if not bgSelected then
  bgSelected = colors.black
elseif bgSelected == colors.white then
  term.setTextColor(colors.black)
end
if not tSelected then
  tSelected = colors.white
elseif tSelected == colors.white then
  term.setTextColor(colors.black)
end
if not textSelected then
  textSelected = " "
end
term.setBackgroundColor(bgSelected)
term.write("B")
term.setBackgroundColor(tSelected)
term.write("T")
for i=1,16 do
  i=i-1
  term.setCursorPos(1,i+2)
  term.setBackgroundColor(2^i)
  term.write("  ")
end
term.setCursorPos(1,18)
term.setBackgroundColor(colors.black)
if not textSelected then
  textSelected = " "
elseif string.len(textSelected) > 1 then
  textSelected = string.sub(textSelected,1,1)
end
term.setTextColor(colors.gray)
term.setBackgroundColor(colors.black)
term.write(transparentIcon)
term.setTextColor(tSelected)
term.setBackgroundColor(bgSelected)
term.write(textSelected)
end
function writeMenuBar(booly)
menuStatus = booly
term.setBackgroundColor(colors.black)
if booly == true then
  term.setCursorPos(1,tY)
  term.clearLine()
  if not menuItemSelected then
   menuItemSelected = 1
  end
  term.setTextColor(colors.white)
  term.write(" Save  Exit ")
  term.setCursorPos(6*menuItemSelected-5,tY)
  term.setTextColor(colors.yellow)
  term.write("[")
  term.setCursorPos(6*menuItemSelected,tY)
  term.write("]")
elseif booly == false then
  term.setCursorPos(1,tY)
  term.setTextColor(colors.yellow)
  term.clearLine()
  if saved == true then
   term.write("Saved to "..args[1])
  else
   term.write("Press Ctrl to access menu")
  end
  term.setCursorPos(tX,tY)
  term.setTextColor(colors.lightGray)
  term.write("?")
end
end
end
if #args > 0 then
init()
menuStatus = false
saved = false
writeMenuBar(menuStatus)
menuItemSelected = 1
drawData(3,0)
drawMenu()
eventHandler()
end


Usage:


API functions:

.drawImage(<file name>,<x pos>,<y pos>,[redirection object])
.overWrite(<Text>,<x pos>,<y pos>,<text color>)

Code:
Spoiler

transparentIcon = "-"
args = {...}
tX, tY = term.getSize()
function drawImage(file,xSet,ySet,redirection)
init()
lastImage = file
lastX = xSet
lastY = ySet
lastRedirection = redirection
if redirection then
  current = term.current()
  term.redirect(redirection)
end
drawData(xSet,ySet,file)
if redirection then
  term.redirect(current)
end
endfunction overWrite(textSet,xSet,ySet,colorSet)
init()
exists = true
if not lastImage then
  error("Use drawImage first!")
end
if not writeBuffer then
  writeBuffer = {}
end
if not writeBuffer[lastImage] then
  writeBuffer[lastImage] = {}
end
plusPos = 0
for char in string.gmatch(textSet,".") do
  if not writeBuffer[lastImage][xSet+plusPos] then
   writeBuffer[lastImage][xSet+plusPos] = {}
  end
  if not writeBuffer[lastImage][xSet+plusPos][ySet] then
   writeBuffer[lastImage][xSet+plusPos][ySet] = {colors.black," ",colors.white}
  end
  writeBuffer[lastImage][xSet+plusPos][ySet][2] = char
  writeBuffer[lastImage][xSet+plusPos][ySet][3] = colorSet
  plusPos = plusPos + 1
end
drawImage(lastImage,lastX,lastY,lastRedirection)
end
function init()
function eventHandler()
while true do
  event = {os.pullEvent()}
  if event[1] == "key" then
   if event[2] == keys.leftCtrl or event[2] == 157 then
	menuStatus = not menuStatus
	writeMenuBar(menuStatus)
   end
   if menuStatus == true then
	if event[2] == keys.right or event[2] == keys.left then
	 if menuItemSelected == 1 then
	  menuItemSelected = 2
	 else
	  menuItemSelected = 1
	 end
	 writeMenuBar(menuStatus)
	elseif event[2] == keys.enter then
	 if menuItemSelected == 1 then
	  save()
	  writeMenuBar(false)
	 else
	  term.setTextColor(colors.yellow)
	  term.setBackgroundColor(colors.black)
	  term.clear()
	  term.setCursorPos(1,1)
	  error()
	 end
	end
   else  
	if event[2] == keys.right then
	 drawData(offSetX-1,offSetY)
	 drawMenu()
	 writeMenuBar(menuStatus)
	elseif event[2] == keys.left then
	 drawData(offSetX+1,offSetY)
	 drawMenu()
	 writeMenuBar(menuStatus)
	elseif event[2] == keys.up then
	 drawData(offSetX,offSetY+1)
	 drawMenu()
	 writeMenuBar(menuStatus)
	elseif event[2] == keys.down then
	 drawData(offSetX,offSetY-1)
	 drawMenu()
	 writeMenuBar(menuStatus)
	end
   end
  end
  if event[1] == "mouse_click" or event[1] == "mouse_drag" then
   if event[3] > 2 and event[4] ~= tY then
	insertItem(event[3],event[4],event[2])
   elseif event[4] < 18 and event[4] > 1 then
	if event[3] == 1 then
	 bgSelected = 2^(event[4]-2)
	elseif event[3] == 2 then
	 tSelected = 2^(event[4]-2)
	end
	drawMenu()
   elseif event[4] == tY - 1 and event[3] == 1 then
	setLetter()
	drawData(offSetX,offSetY)
	drawMenu()
   elseif event[3] == tX and event[4] == tY and menuStatus == false then
	writeHelp()
   end
  end
  if event[1] == "char" then
   textSelected = string.sub(event[2],1,1)
   drawMenu()
  end
  --drawData(offSetX,offSetY)
end
endfunction writeHelp()
term.setBackgroundColor(colors.black)
term.setTextColor(colors.green)
term.clear()
term.setCursorPos(1,1)
term.write("Help:")
term.setTextColor(colors.white)
term.setCursorPos(1,3)
print("Usage:")
term.setTextColor(colors.lightGray)
print("  Select color: Click on the color on the left")
print("  Change draw char: Press a key on the keyboard")
print("  Change transparent icon: Click on the icon's char in the menu")
print("  Change text color: Click on a color in the menu on the right side")
print("  Change background color: Click on a color in the menu on the left side")
term.setTextColor(colors.white)
print()
print("Controls:")
term.setTextColor(colors.lightGray)
print("  Arrow keys to pan")
print("  Left mouse button to select and draw")
print("  Right mouse button to delete")
print("  Ctrl to open menu")
print()
term.setTextColor(colors.white)
term.write("Click a mouse button to exit.")
term.setTextColor(colors.orange)
term.setCursorPos(tX-9,1)
term.write("API help >")
event = {os.pullEvent("mouse_click")}
if event[3] > tX-10 and event[4] == 1 then
  drawAPIhelp()
end
drawData(offSetX,offSetY)
drawMenu()
writeMenuBar(menuStatus)
end
function drawAPIhelp()
term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.orange)
print("API help menu:")
print()
term.setTextColor(colors.white)
print("Drawing an image: ")
term.setTextColor(colors.lightGray)
print(shell.getRunningProgram(),".drawImage(<file name>,<x pos>,<y pos>,[redirection object])")
print()
term.setTextColor(colors.white)
print("Overlaying text on the last image:")
term.setTextColor(colors.lightGray)
print(shell.getRunningProgram(),".overWrite(<Text>,<x pos>,<y pos>,<text color>")
print()
term.setTextColor(colors.red)
print("Overwriting text will only work AFTER drawing an image!")
term.setTextColor(colors.white)
print()
print("Example:")
term.setTextColor(colors.lightGray)
print("os.loadAPI(\"",shell.getRunningProgram(),"\")")
print(shell.getRunningProgram(),".drawImage(\"myPicture\",1,1)")
print(shell.getRunningProgram(),".overWrite(\"Hello!\",2,3,colors.orange)")
os.pullEvent("mouse_click")
endfunction setLetter()
term.setBackgroundColor(colors.red)
term.setTextColor(colors.black)
for i=1,4 do
  term.setCursorPos(tX/2-11,(tY/2-4)+i)
  term.write("					 ")
end
term.setCursorPos(tX/2-10,tY/2-2)
term.write("Change transparancy")
term.setCursorPos(tX/2-10,tY/2-1)
term.write("character to: (key)")
event = {os.pullEvent("char")}
transparentIcon = event[2]
end
function insertItem(xPos,yPos,modeSet)
if saved == true then
  saved = false
  writeMenuBar(false)
end
--bgSelected
--tSelected
--textSelected
if not painted then
  painted = {}
end
if not painted[xPos-offSetX] then
  painted[xPos-offSetX] = {}
end
if modeSet == 1 then
   if not textSelected then
	textSelected = " "
   end
   TMPtextSelected = textSelected
   painted[xPos-offSetX][yPos-offSetY] = {bgSelected,textSelected,tSelected}
   term.setBackgroundColor(bgSelected)
   term.setTextColor(tSelected)
  else
   TMPtextSelected = transparentIcon
   term.setBackgroundColor(colors.black)
   term.setTextColor(colors.gray)
   painted[xPos-offSetX][yPos-offSetY] = nil
end
term.setCursorPos(xPos,yPos)
term.write(TMPtextSelected)
end--if #args ~= 1 then
-- print("Usage: "..shell.getRunningProgram().." <path>")
-- return
--end
if args[1] and fs.exists(args[1]) == true then
buff = fs.open(args[1],"r")
previousData = buff.readAll()
buff.close()
processed = string.sub(previousData,43)
painted = textutils.unserialize(processed)
else
painted = {}
endfunction save()
file = fs.open(args[1],"w")
file.write("error('This is an image, not a program!')\n"..textutils.serialize(painted))
file.close()
saved = true
end
function drawData(xStart, yStart, file)
offSetX = xStart
offSetY = yStart
if not file then
  term.setBackgroundColor(colors.black)
  term.setTextColor(colors.gray)
  transparentLine = ""
  for x=1,tX-2 do
   transparentLine = transparentIcon..transparentLine
  end
  for y=1,tY-1 do
   term.setCursorPos(3,y)
   term.write(transparentLine)
  end
else
  if fs.exists(file) == false then
   error("File given doesnt exists! file name: "..file)
  else
   local fileD = fs.open(file,"r")
   raw = fileD.readAll()
   --ignoreL = string.len(fileD.readLine(1))
   processed = string.sub(raw,43)
   --term.redirect(term.native())
  -- textutils.pagedPrint(processed)
   painted = textutils.unserialize(processed)
   fileD.close()
  end
end
if not painted then
  painted = {}
end
paintedF = painted
count = 0
repeat ---------
count = count + 1
for xPos,v in pairs(paintedF) do
  for yPos in pairs (paintedF[xPos]) do
	overWrite = true
	if not lastImage or not writeBuffer or not writeBuffer[lastImage] then
	 overWrite = false
	end
	if overWrite == true then
	 if not writeBuffer[lastImage][xPos] then
	  overWrite = false
	 end
	end
	if overWrite == true then
	 if not writeBuffer[lastImage][xPos][yPos] then
	  overWrite = false
	 end
	end
	if overWrite == false then
	 bgColor = paintedF[xPos][yPos][1]
	 text = paintedF[xPos][yPos][2]
	 tColor = paintedF[xPos][yPos][3]
	else
	 if painted and painted[xPos] and painted[xPos][yPos] and painted[xPos][yPos][1] then
	  bgColor = painted[xPos][yPos][1]
	  else
	  bgColor = colors.black
	 end
	 --if not bgColor then
	--  bgColor = colors.black
	 --end
	 text = writeBuffer[lastImage][xPos][yPos][2]
	 tColor = writeBuffer[lastImage][xPos][yPos][3]
	end
	if not tColor then
	 tColor = colors.white
	end
	if not text then
	 text = " "
	end
	term.setCursorPos(xPos+xStart,yPos+yStart)
	term.setBackgroundColor(bgColor)
	term.setTextColor(tColor)
	term.write(text)
   end
  end
  if count == 1 and writeBuffer and lastImage then
   paintedF = writeBuffer[lastImage]
  elseif count == 1 and not lastImage or not writeBuffer then
   count = 2
  end
until count == 2
term.setCursorPos(1,tY)
endfunction drawMenu()
term.setCursorPos(1,1)
term.setTextColor(colors.white)
if not bgSelected then
  bgSelected = colors.black
elseif bgSelected == colors.white then
  term.setTextColor(colors.black)
end
if not tSelected then
  tSelected = colors.white
elseif tSelected == colors.white then
  term.setTextColor(colors.black)
end
if not textSelected then
  textSelected = " "
end
term.setBackgroundColor(bgSelected)
term.write("B")
term.setBackgroundColor(tSelected)
term.write("T")
for i=1,16 do
  i=i-1
  term.setCursorPos(1,i+2)
  term.setBackgroundColor(2^i)
  term.write("  ")
end
term.setCursorPos(1,18)
term.setBackgroundColor(colors.black)
if not textSelected then
  textSelected = " "
elseif string.len(textSelected) > 1 then
  textSelected = string.sub(textSelected,1,1)
end
term.setTextColor(colors.gray)
term.setBackgroundColor(colors.black)
term.write(transparentIcon)
term.setTextColor(tSelected)
term.setBackgroundColor(bgSelected)
term.write(textSelected)
end
function writeMenuBar(booly)
menuStatus = booly
term.setBackgroundColor(colors.black)
if booly == true then
  term.setCursorPos(1,tY)
  term.clearLine()
  if not menuItemSelected then
   menuItemSelected = 1
  end
  term.setTextColor(colors.white)
  term.write(" Save  Exit ")
  term.setCursorPos(6*menuItemSelected-5,tY)
  term.setTextColor(colors.yellow)
  term.write("[")
  term.setCursorPos(6*menuItemSelected,tY)
  term.write("]")
elseif booly == false then
  term.setCursorPos(1,tY)
  term.setTextColor(colors.yellow)
  term.clearLine()
  if saved == true then
   term.write("Saved to "..args[1])
  else
   term.write("Press Ctrl to access menu")
  end
  term.setCursorPos(tX,tY)
  term.setTextColor(colors.lightGray)
  term.write("?")
end
end
end
if #args > 0 then
init()
menuStatus = false
saved = false
writeMenuBar(menuStatus)
menuItemSelected = 1
drawData(3,0)
drawMenu()
eventHandler()
end

Feedback is apreciated and if you manage to find bugs in the code, let me know and I will see what I can do!

Thank you for your attention and happy programming!
Edited on 11 March 2015 - 02:59 PM
superaxander #2
Posted 27 February 2015 - 03:53 PM
This looks really nice. I can't wait to see it used in some programs!
Terminator_NL #3
Posted 27 February 2015 - 04:07 PM
Thank you very much, I would like to know if someone actually uses it, If anyone uses the program, do they mind posting some screenshots? I made this program to make the lives of the programmers easier :D/> (and I am curious what it will be used for, haha)
Edited on 27 February 2015 - 03:07 PM
Creator #4
Posted 27 February 2015 - 08:12 PM
Cool, I can't say I need it right now, but you put some effort in there!

~Creator
Creator #5
Posted 05 March 2015 - 09:28 PM
Can I use it in my OS. With credit ofc. ;)/>
Terminator_NL #6
Posted 06 March 2015 - 03:19 PM
Can I use it in my OS. With credit ofc. ;)/>
Yes sure!! I would love that!
Creator #7
Posted 06 March 2015 - 03:33 PM
Well I actually kind of designed my own similar function, but it doesnt work correctly. Here it is:


--BetterPaintAPI--
----by Creator----
local function drawPixel(x,y,character,fgColor,bgColor)
term.setCursorPos(x,y)
term.setBackgroundColor(bgColor)
term.setTextColor(fgColor)
term.write(string.sub(character,1,1))
end
function advancedPaint(x,y,image,text)
local textTable = {}
local xPos = 1
local yPos = 1
local currColor = colors.black
local buffer = {}
for token in string.gmatch(text,"[^%%]+") do
  buffer[#buffer+1] = token
end
print("3")
print(textutils.serialize(buffer))
for i,v in pairs(buffer) do
  if string.sub(v,1,1) == "<" and string.sub(v,-1,-1) == ">"then
   print("ana")
   local toAnalize = string.sub(v,2,-2)
   if toAnalize == "newLine" then
    xPos = 1
    yPos = yPos + 1
   else
    local internalBuffer = {}
    for token in string.gmatch(toAnalize,"[^:]+") do
	 internalBuffer[#internalBuffer+1] = token
    end
    if internalBuffer[1] == "fgColor" then
	 currColor = colors[internalBuffer[2]]
    end
   end
  else
   print("str")
   for k=1,#v do
    currLeter = string.sub(v,k,k)
    textTable[yPos][xPos][1] = currLeter
    textTable[yPos][xPos][2] = currColor
    textTable[yPos][xPos][3] = image[yPos][xPos] or colors.white
   end
  end
end
print("4")
print(textutils.serialize(textTable))
for i,v in pairs(textTable) do
  for k,m in pairs(v) do
   drawPixel(k+x-1,i+y-1,m[1],m[2],m[3])
  end
end
print("5")
end
Terminator_NL #8
Posted 06 March 2015 - 08:04 PM
Well I actually kind of designed my own similar function, but it doesnt work correctly. Here it is:

-snip-

I dont know why you would do that, does my api need more functions? Im adding paintutils conversion support as we speak btw :P/>
Also, what's the error?
CreeperWiz #9
Posted 06 March 2015 - 11:28 PM
please make a pastebin!

also i keep getting a error string "draw" 18 '=' expected
Creator #10
Posted 07 March 2015 - 11:01 AM
there is nothing wrong with yours. it is just that I was too lazy to redraw the icons and i like doing my own stuff
Terminator_NL #11
Posted 07 March 2015 - 11:09 AM
Haha okay :P/>
Geforce Fan #12
Posted 07 March 2015 - 11:02 PM
Wish I'd known about this before hard coding slides…
Terminator_NL #13
Posted 09 March 2015 - 09:50 PM
Updated to version 2:
Changelog:
[indent=1]added paintutils converter[/indent]
[indent=1]Changed thread lay-out to a somewhat more "organized" look[/indent]
[indent=1]Uploaded PNG converter for convienience sake[/indent]
Creator #14
Posted 12 March 2015 - 08:41 PM
I am just gonna go with yours. Writting an os is so much work and now having to write that api is too much.

Thanks a lot
Creator #15
Posted 12 March 2015 - 09:26 PM
I will include BetterPaint as an object type in the Interact API (my GUI API, check at the link I gave you). Is that OK? I think it (betterpaint) is super useful. ;)/>
Terminator_NL #16
Posted 13 March 2015 - 04:23 PM
I will include BetterPaint as an object type in the Interact API (my GUI API, check at the link I gave you). Is that OK? I think it (betterpaint) is super useful. ;)/>
That's completely fine! I feel honored that you use my api.
if you feel like you need more api functions or something I have not noticed, feel free to post them here and I will try to add them!
Happy coding! :)/>
Creator #17
Posted 15 March 2015 - 05:34 PM
A super nice feature would be to be able to print our mega advanced art with your mindblowing program. ;)/> (#grammar, #writingLitteraryLanguage)

~Creator
Terminator_NL #18
Posted 15 March 2015 - 10:19 PM
A super nice feature would be to be able to print our mega advanced art with your mindblowing program. ;)/> (#grammar, #writingLitteraryLanguage)

~Creator
You can. paint.drawImage(<file>, <xPos>, <yPos> [,redirection target]) does that for you. the same way as paintutils does
if no redirection target is given, it will simply print in the terminal. :D/>