Author Topic: [Lua] Image Editor  (Read 21783 times)

0 Members and 2 Guests are viewing this topic.

Offline Chockosta

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 447
  • Rating: +169/-6
    • View Profile
[Lua] Image Editor
« on: August 06, 2011, 12:38:27 pm »
Hello everybody !

Spoiler For Old first post:
A while ago, p2 sent me this PM :
Quote from: p2
can you please try to make a drawing-program for the NI NSPIRE CX CAS?

So I tried that.

It already features :
-Opening and saving ti.images
-Zoom in and zoom out
-A nice color selecting window
-Error messages
-Transparency support

And it will feature :
-Creating blanks images Done
-Pixel-per-pixel drawing Done
-Lines, squares and circles drawing Done
-Text
-Opening and saving BMP files (maybe)

The script is almost 500 lines long.
To open an image, it has to be saved in a string in a "Calculator" application.
I had to rewrite TI.images loading and displaying, because in Lua, "\000" can't be saved in a string. Thanks to Inspired Lua for this page !
It was supposed to be called Paintbrush, but Google told me that a MacOS software is already called "Paintbrush". Do you have any suggestions ?

EDIT 08/07/2011 : Now you can fill and erase pixels.

EDIT 30/10/2011 : To see the last version, go HERE


The last version is nSpaint 0.7. It features :


-Two editors : nSpaint for images and nAnima for animations
-A lot of tools : scroll, draw, erase, fill, pick, circle, line, rectangle, fill circle, fill rectangle.
-A native-like GUI (in nAnima too)
-Save, open or create images of any dimensions
-Transparency support
-A file manager, which can be used to delete images (in nAnima too)
-A tool to copy the current image code to the clipboard (really useful to Lua developpers!)
-A tool to paste an image if there's one in the clipboard
-Undo and redo! (5 times max)
-A option to erase all the image
-A nice color selecter
-Tools to flip/rotate the image
-A filter which replace a color with another one
-A filter which erases a color
-Two filters to increase and decrease brightness
-A 'help' window for each tool
-A splash screen (in nAnima too)
-You can move the cursor with the mouse
-The image is automatically moved when the cursor goes off the screen
-The cursor is moved when you scroll

DOWNLOAD

Screenies:


(The attached screenies are old ones)
« Last Edit: April 11, 2012, 12:54:48 pm by Chockosta »

Offline Adriweb

  • Editor
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1708
  • Rating: +229/-17
    • View Profile
    • TI-Planet.org
Re: [Lua] Image Editor
« Reply #1 on: August 06, 2011, 12:40:15 pm »
Woooow

This is awesome.

Congratulations.

Will definitely download and use !!
« Last Edit: August 06, 2011, 12:41:48 pm by adriweb »
My calculator programs
TI-Planet.org co-admin.
TI-Nspire Lua programming : Tutorials  |  API Documentation

Offline Chockosta

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 447
  • Rating: +169/-6
    • View Profile
Re: [Lua] Image Editor
« Reply #2 on: August 06, 2011, 12:40:59 pm »
Well, for now you can't edit pictures, just load and save them :D

Offline Adriweb

  • Editor
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1708
  • Rating: +229/-17
    • View Profile
    • TI-Planet.org
Re: [Lua] Image Editor
« Reply #3 on: August 06, 2011, 12:43:05 pm »
Well, jimbauwens' TI.Image javascript library is available on his website, so you can probably get some interesting editing stuff from there :P


BTW, as usual... source code ? :P
My calculator programs
TI-Planet.org co-admin.
TI-Nspire Lua programming : Tutorials  |  API Documentation

Offline Chockosta

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 447
  • Rating: +169/-6
    • View Profile
Re: [Lua] Image Editor
« Reply #4 on: August 06, 2011, 12:51:00 pm »
(It will change very soon)
There isn't any class because I don't like object-oriented programmation... Sorry :P

Spoiler For Spoiler:
Data.lua :
Code: [Select]
--DATA
--drawing
status="drawing"
color={225,170,0}
imgString=nil
imgTable=nil
imgZoom=1
imgName="Open any file"
--color select
newColor={200,100,255}
selColor=1
--text request
requested=""
rqstr=""
--error
errtype=""


--MENU
function menuNew() on.charIn("N") end
function menuOpen() on.charIn("O") end
function menuSave() on.charIn("S") end
function menuZIn() on.charIn("+") end
function menuZOut() on.charIn("-") end
function menuDraw() on.charIn("d") end
function menuPaint() on.charIn("p") end
function menuErase() on.charIn("e") end
function menuCHex() on.charIn("h") end
function menuCSel() on.charIn("s") end

menu={
{"File",
 {"New (Shift+n)",menuNew},
 {"Open (Shift+o)",menuOpen},
 {"Save (Shift+s)",menuSave}
},
{"Edit",
 {"Zoom in (+)",menuZIn},
 {"Zoom out (-)",menuZOut}
},
{"Tools",
 {"Draw (d)",menuDraw},
 {"Paint (p)",menuPaint},
 {"Erase (e)",menuErase}
},
{"Color",
 {"Hexadecimal (h)",menuCHex},
 {"Select (s)",menuCSel}
}}
toolpalette.register(menu)
Functions.lua
Code: [Select]
--MATHTOOLS
mathTools={}

function mathTools.base10to2(n)
 local str
 str=""
 if n~=0 then
  while n~=1 do
   str=str..tostring(n%2)
   n=math.floor(n/2)
  end
  str=str..tostring(n%2)
  return string.reverse(str)
 else
  return "0"
 end
end

function mathTools.base2to10(n)
 local num = 0
 local ex = string.len(n) - 1
 local l = 0
 l = ex + 1
 for i = 1, l do
  b = string.sub(n, i, i)
  if b == "1" then
   num = num + 2^ex
  end
  ex = ex - 1
 end
 return num
end

function mathTools.int2Hex(int)
 if int<10 then
  return tostring(int)
 else
  if int==10 then return "A"
  elseif int==11 then return "B"
  elseif int==12 then return "C"
  elseif int==13 then return "D"
  elseif int==14 then return "E"
  elseif int==15 then return "F"
  end
 end
end



--MISCELLANEOUS


function width() return platform.window:width() end
function height() return platform.window:height() end
function refresh() platform.window:invalidate() end


function strch(str,ch)
 local test
 test=nil
 for i=1,string.len(str),1 do
  if string.sub(str,i,i)==ch then
   test=1
  end
 end
 return test
end

function saveFile()
 if rqstr=="" then
  status="error"
  errtype="Please type a name"
 elseif strch("0123456789",string.sub(rqstr,1,1)) then
  status="error"
  errtype="Invalid name"
 else
  var.store(rqstr,imgString)
  imgName=rqstr
 end
end

function loadFile()
 local test
 test=var.recall(rqstr)
 if not test then
  status="error"
  errtype="File does not exist"
 elseif type(test)~="string" then
  status="error"
  errtype="Invalid file"
 else
  imgZoom=1
  imgString=test
  imgTools.img2table(imgString)
  imgName=rqstr
 end
end

function loadHexColor()
 local isHex,tmptable
 isHex=1
 tmptable={}
 if string.len(rqstr)==6 then
  for i=1,6,1 do
   currentch=string.sub(rqstr,i,i)
   if strch("0123456789",currentch) then
    tmptable[i]=tonumber(currentch)
   elseif strch("Aa",currentch) then tmptable[i]=10
   elseif strch("Bb",currentch) then tmptable[i]=11
   elseif strch("Cc",currentch) then tmptable[i]=12
   elseif strch("Dd",currentch) then tmptable[i]=13
   elseif strch("Ee",currentch) then tmptable[i]=14
   elseif strch("Ff",currentch) then tmptable[i]=15
   else isHex=nil end
  end
 else isHex=nil
 end
 if isHex then
  color={tmptable[1]*16+tmptable[2],tmptable[3]*16+tmptable[4],tmptable[5]*16+tmptable[6]}
 else
  status="error"
  errtype="Invalid hexadecimal"
 end
end


imgTools.lua
Code: [Select]
imgTools={}

function imgTools.getPixel(byte1,byte2)
 local str2
 str2=imgTools.eightChars(mathTools.base10to2(tonumber(byte2)))..imgTools.eightChars(mathTools.base10to2(tonumber(byte1)))
 return {tonumber(string.sub(str2,1,1)),mathTools.base2to10(string.sub(str2,2,6)),mathTools.base2to10(string.sub(str2,7,11)),mathTools.base2to10(string.sub(str2,12,16))}
end

function imgTools.getSize(img)
 imgWidth=mathTools.base2to10(mathTools.base10to2(tonumber(string.sub(img,10,12)..string.sub(img,7,9)..string.sub(img,4,6)..string.sub(img,1,3))))
 imgHeight=mathTools.base2to10(mathTools.base10to2(tonumber(string.sub(img,22,24)..string.sub(img,19,21)..string.sub(img,16,18)..string.sub(img,13,15))))
end

function imgTools.threeNumbers(nb)
 if string.len(tostring(nb))==1 then
  return "00"..tostring(nb)
 elseif string.len(tostring(nb))==2 then
  return "0"..tostring(nb)
 else
  return tostring(nb)
 end
end

function imgTools.eightChars(str)
 return string.rep("0",8-string.len(str))..str
end

function imgTools.convertChars(img)
 local finished,img2,index
 index=1
 img2=""
 finished=nil
 while not finished do
  if string.sub(img,index,index)~=[[\]] then
   img2=img2..imgTools.threeNumbers(string.byte(string.sub(img,index,index)))
   index=index+1
  else
   img2=img2..string.sub(img,index+1,index+3)
   index=index+4
  end
  if index>string.len(img) then
   finished=1
  end
 end
 return img2
end

function imgTools.img2table(str)
 local index
 str2=imgTools.convertChars(str)
 imgTable={}
 imgTools.getSize(str2)
 for raw=1,imgHeight do
  imgTable[raw]={}
  for column=1,imgWidth do
   index=(column-1)*6+61+(raw-1)*6*imgWidth
   imgTable[raw][column]=imgTools.getPixel(string.sub(str2,index,index+2),string.sub(str2,index+3,index+5))
  end
 end
end

function imgTools.drawTable(gc,x,y)
 for raw=1,imgHeight do
  for column=1,imgWidth do
   if imgTable[raw][column][1]==1 then
    gc:setColorRGB(imgTable[raw][column][2]*8,imgTable[raw][column][3]*8,imgTable[raw][column][4]*8)
    gc:fillRect((column-1)*imgZoom+x,(raw-1)*imgZoom+y,imgZoom,imgZoom)
    gc:setColorRGB(0,0,0)
    gc:setPen("thin","smooth")
    gc:drawRect(x-1,y-1,imgWidth*imgZoom+1,imgHeight*imgZoom+1)
   end
  end
 end
end


Events.lua
Code: [Select]
--EVENTS
function on.backspaceKey()
 if status=="requesting" then
  rqstr=string.sub(rqstr,1,string.len(rqstr)-1)
  platform.window:invalidate()
 end
end

function on.charIn(ch)
 if status=="drawing" then
  if ch=="+" and imgZoom<8 then
   imgZoom=imgZoom*2
  elseif ch=="-" and imgZoom>1 then
   imgZoom=imgZoom/2
  elseif ch=="O" then
   status="requesting"
   rqstr=""
   requested="File name"
  elseif ch=="S" then
   if not imgString then
    status="error"
    errtype="No opened file"
   else
    status="requesting"
    rqstr=imgName
    requested="Save as"
   end
  elseif ch=="s" then
   status="selectingColor"
   selColor=1
   newColor={math.floor(color[1]/5)*5,math.floor(color[2]/5)*5,math.floor(color[3]/5)*5}
  elseif ch=="h" then
   status="requesting"
   rqstr=""
   requested="Hex code"
  end
 elseif status=="requesting" and string.len(rqstr)<10 and strch("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",ch) then
  rqstr=rqstr..ch
 end
 refresh()
end

function on.escapeKey()
 status="drawing"
 refresh()
end

function on.enterKey()
 if status=="selectingColor" then
  color=newColor
  status="drawing"
 elseif status=="requesting" then
  status="drawing"
  if requested=="Hex code" then
   loadHexColor()
  elseif requested=="File name" then
   rqstr=string.lower(rqstr)
   loadFile()
  elseif requested=="Save as" then
   rqstr=string.lower(rqstr)
   saveFile()
  end
 elseif status=="error" then
  status="drawing"
 end
 refresh()
end

function on.arrowKey(ar)
 if status=="selectingColor" then
  if ar=="up" then
   selColor=selColor-1
  elseif ar=="down" then
   selColor=selColor+1
  elseif ar=="right" and newColor[selColor]<251 then
   newColor[selColor]=newColor[selColor]+5
  elseif ar=="left" and newColor[selColor]>4 then
   newColor[selColor]=newColor[selColor]-5
  end
  if selColor>3 then
   selColor=1
  elseif selColor<1 then
   selColor=3
  end
 end
 refresh()
end
Drawing.lua
Code: [Select]

--DRAWING
function drawColorSelect(gc)
 gc:setColorRGB(200,200,255)
 gc:fillRect(width()/2-75,height()/2-50,150,100)
 gc:setColorRGB(0,0,0)
 gc:fillRect(width()/2-75,height()/2-50,150,15)
 gc:setPen("thin","smooth")
 gc:drawRect(width()/2-75,height()/2-50,150,100)
 gc:setFont("sansserif","r",10)
 gc:setColorRGB(255,255,255)
 gc:drawString("Select your color",width()/2-73,height()/2-53,"top")
 gc:setColorRGB(0,0,0)
 gc:drawString("Red :",width()/2-73,height()/2-35,"top")
 gc:drawString("Green :",width()/2-73,height()/2-20,"top")
 gc:drawString("Blue :",width()/2-73,height()/2-5,"top")
 for i=0,63 do
  gc:setColorRGB(i*4,newColor[2],newColor[3])
  gc:fillRect(width()/2-23+i,height()/2-30,1,10)
  gc:setColorRGB(newColor[1],i*4,newColor[3])
  gc:fillRect(width()/2-23+i,height()/2-15,1,10)
  gc:setColorRGB(newColor[1],newColor[2],i*4)
  gc:fillRect(width()/2-23+i,height()/2,1,10)
 end
 gc:setColorRGB(0,0,0)
 gc:drawRect(width()/2-23,height()/2-46+selColor*15,64,11)
 for i=1,3 do
  gc:drawString(tostring(newColor[i]),width()/2+52,height()/2-50+i*15,"top")
  gc:fillRect(width()/2-24+newColor[i]/4,height()/2-47+i*15,3,14)
 end
 gc:setColorRGB(color[1],color[2],color[3])
 gc:fillRect(width()/2-70,height()/2+20,30,20)
 gc:setColorRGB(newColor[1],newColor[2],newColor[3])
 gc:fillRect(width()/2-28,height()/2+20,30,20)
 gc:setColorRGB(0,0,0)
 gc:drawRect(width()/2-70,height()/2+20,30,20)
 gc:drawRect(width()/2-28,height()/2+20,30,20)
 gc:drawString(mathTools.int2Hex(math.floor(newColor[1]/16))..mathTools.int2Hex(newColor[1]%16)..mathTools.int2Hex(math.floor(newColor[2]/16))..mathTools.int2Hex(newColor[2]%16)..mathTools.int2Hex(math.floor(newColor[3]/16))..mathTools.int2Hex(newColor[3]%16),width()/2+20,height()/2+20,"top")
 gc:drawString("Old     New",width()/2-65,height()/2+21,"top")
end

function drawRequest(gc,msg)
 gc:setColorRGB(200,200,255)
 gc:fillRect(width()/2-75,height()/2-25,150,50)
 gc:setColorRGB(0,0,0)
 gc:setPen("thin","smooth")
 gc:drawRect(width()/2-75,height()/2-25,150,50)
 gc:fillRect(width()/2-75,height()/2-25,150,15)
 gc:setFont("sansserif","r",10)
 gc:setColorRGB(255,255,255)
 gc:drawString(msg,width()/2-70,height()/2-28,"top")
 gc:setColorRGB(0,0,0)
 gc:drawRect(width()/2-70,height()/2,140,20)
 gc:drawString(rqstr,width()/2-65,height()/2,"top")
end

function drawError(gc)
 gc:setColorRGB(200,200,255)
 gc:fillRect(width()/2-75,height()/2-20,150,40)
 gc:setColorRGB(0,0,0)
 gc:setPen("thin","smooth")
 gc:drawRect(width()/2-75,height()/2-20,150,40)
 gc:fillRect(width()/2-75,height()/2-20,150,15)
 gc:setFont("sansserif","r",10)
 gc:setColorRGB(255,255,255)
 gc:drawString("Error",width()/2-73,height()/2-23,"top")
 gc:setColorRGB(0,0,0)
 gc:drawString(errtype,width()/2-70,height()/2-5,"top")
end

function on.paint(gc)
 gc:setColorRGB(color[1],color[2],color[3])
 gc:fillRect(0,0,20,15)
 gc:setColorRGB(0,0,0)
 gc:setPen("thin","smooth")
 gc:drawRect(0,0,20,15)
 gc:setFont("sansserif","r",10)
 gc:drawString(imgName.." ("..tostring(imgZoom*100).."%)",25,0,"top")
 if imgTable then
  imgTools.drawTable(gc,30,30)
 end
 if status=="selectingColor" then
  drawColorSelect(gc)
 elseif status=="requesting" then
  drawRequest(gc,requested)
 elseif status=="error" then
  drawError(gc)
 end
 gc:setColorRGB(0,0,0)
 gc:setFont("sansserif","r",8)
 gc:drawString("Lua Paintbrush - Par Loic Pujet",10,height()-12,"top")
end

Offline ExtendeD

  • CoT Emeritus
  • LV8 Addict (Next: 1000)
  • *
  • Posts: 825
  • Rating: +167/-2
    • View Profile
Re: [Lua] Image Editor
« Reply #5 on: August 06, 2011, 01:21:46 pm »
Nice tool Chockosta :)
Ndless.me with the finest TI-Nspire programs

Offline Hayleia

  • Programming Absol
  • Coder Of Tomorrow
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3367
  • Rating: +393/-7
    • View Profile
Re: [Lua] Image Editor
« Reply #6 on: August 06, 2011, 01:55:26 pm »
This is a great tool ! Why don't I have an nspire ?! :'(
It was supposed to be called Paintbrush, but Google told me that a MacOS software is already called "Paintbrush". Do you have any suggestions ?
Maybe a mix between MS Paint and Nspire that gives nSpaint ?
I own: 83+ ; 84+SE ; 76.fr ; CX CAS ; Prizm ; 84+CSE
Sorry if I answer with something that seems unrelated, English is not my primary language and I might not have understood well. Sorry if I make English mistakes too.

click here to know where you got your last +1s

Offline Jim Bauwens

  • Lua! Nspire! Linux!
  • Editor
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1881
  • Rating: +206/-7
  • Linux!
    • View Profile
    • nothing...
Re: [Lua] Image Editor
« Reply #7 on: August 06, 2011, 02:32:17 pm »
Looks very nice!
Good to use with on calc editors :)

Quote
Thanks to Inspired Lua for this page !
I'm glad you liked it :)
I have actually wrote a better, simpler version, but haven't taken the time to upload it.

Offline DJ Omnimaga

  • Former TI programmer
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55846
  • Rating: +3151/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • DJ Omnimaga Music
Re: [Lua] Image Editor
« Reply #8 on: August 06, 2011, 03:52:30 pm »
That's very great! Nice job so far!
In case you are wondering where I went, I left Omni back in 2015 to form CodeWalrus due to various reasons explained back then, but I stopped calc dev in 2016 and am now mostly active on the CW Discord server at https://discord.gg/cuZcfcF



Official Website |T-Shirt store | Reverbnation | Facebook | Youtube | Twitter | Spotify

Offline Chockosta

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 447
  • Rating: +169/-6
    • View Profile
Re: [Lua] Image Editor
« Reply #9 on: August 07, 2011, 11:01:22 am »
Draw and erase tools !
Tomorrow, it will be possible to create new images...

Offline pianoman

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 426
  • Rating: +24/-0
  • ♪♫ ♪♫ ♪♫ ♪♫ ♪♫ ♪♫ ♪♫
    • View Profile
Re: [Lua] Image Editor
« Reply #10 on: August 08, 2011, 03:05:20 pm »
This is absolutely amazing :)
Nice work, as usual!

Offline Deep Toaster

  • So much to do, so much time, so little motivation
  • Administrator
  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 8209
  • Rating: +758/-15
    • View Profile
    • ClrHome
Re: [Lua] Image Editor
« Reply #11 on: August 08, 2011, 03:07:35 pm »
Waoh, awesome! We're seriously short of on-calc Nspire tools right now.




Offline critor

  • Editor
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2079
  • Rating: +439/-13
    • View Profile
    • TI-Planet
Re: [Lua] Image Editor
« Reply #12 on: August 08, 2011, 03:27:59 pm »
Draw and erase tools !

Did you update the 1st post tns attachment?
Unless I have a cache problem, it is byte to byte identic with the one I downloaded 2 days ago...
TI-Planet co-admin.

Offline p2

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 848
  • Rating: +51/-11
  • I'm back :)
    • View Profile
Re: [Lua] Image Editor
« Reply #13 on: August 09, 2011, 06:30:47 am »
Thanx, Chockosta!!!
Looks really great!!
It's exactly what I thought of!!

+1    (+4 wasn't possible...)



Spoiler For Chockosta:
Next project for you:
A program to show .GIF-images and a special software to send them to the TI.
*insert supercool signature*

Offline BrownyTCat

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 420
  • Rating: +37/-8
    • View Profile
Re: [Lua] Image Editor
« Reply #14 on: August 09, 2011, 11:43:25 am »
I just have a small suggestion that could possibly be added later. There's a boolean that returns true if the calc is color, but if it's greyscale it returns false, you could make only one slider for the grey level in the color selector.