Petsox

image.lua

Aug 22nd, 2022
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.43 KB | Source Code | 0 0
  1.  
  2. local computer = require("computer")
  3. local color = require("color")
  4. local unicode = require("unicode")
  5. local fs = require("filesystem")
  6. local gpu = require("component").gpu
  7.  
  8. -------------------------------------------------------------------------------
  9.  
  10. local image = {formatModules = {}}
  11.  
  12. -------------------------------------------------------------------------------
  13.  
  14. function image.getIndex(x, y, width)
  15. return width * (y - 1) + x
  16. end
  17.  
  18. function image.group(picture, compressColors)
  19. local groupedPicture, x, y, background, foreground = {}, 1, 1
  20.  
  21. for i = 1, #picture[3] do
  22. if compressColors then
  23. background, foreground = color.to8Bit(picture[3][i]), color.to8Bit(picture[4][i])
  24. if i % 603 == 0 then
  25. computer.pullSignal(0)
  26. end
  27. else
  28. background, foreground = picture[3][i], picture[4][i]
  29. end
  30.  
  31. groupedPicture[picture[5][i]] = groupedPicture[picture[5][i]] or {}
  32. groupedPicture[picture[5][i]][picture[6][i]] = groupedPicture[picture[5][i]][picture[6][i]] or {}
  33. groupedPicture[picture[5][i]][picture[6][i]][background] = groupedPicture[picture[5][i]][picture[6][i]][background] or {}
  34. groupedPicture[picture[5][i]][picture[6][i]][background][foreground] = groupedPicture[picture[5][i]][picture[6][i]][background][foreground] or {}
  35. groupedPicture[picture[5][i]][picture[6][i]][background][foreground][y] = groupedPicture[picture[5][i]][picture[6][i]][background][foreground][y] or {}
  36.  
  37. table.insert(groupedPicture[picture[5][i]][picture[6][i]][background][foreground][y], x)
  38.  
  39. x = x + 1
  40. if x > picture[1] then
  41. x, y = 1, y + 1
  42. end
  43. end
  44.  
  45. return groupedPicture
  46. end
  47.  
  48. function image.draw(x, y, picture)
  49. local groupedPicture = image.group(picture)
  50. local _, _, currentBackground, currentForeground, gpuGetBackground, imageX, imageY
  51.  
  52. for alpha in pairs(groupedPicture) do
  53. for symbol in pairs(groupedPicture[alpha]) do
  54.  
  55. if not (symbol == " " and alpha == 1) then
  56. for background in pairs(groupedPicture[alpha][symbol]) do
  57.  
  58. if background ~= currentBackground then
  59. currentBackground = background
  60. gpu.setBackground(background)
  61. end
  62.  
  63. for foreground in pairs(groupedPicture[alpha][symbol][background]) do
  64.  
  65. if foreground ~= currentForeground and symbol ~= " " then
  66. currentForeground = foreground
  67. gpu.setForeground(foreground)
  68. end
  69.  
  70. for yPos in pairs(groupedPicture[alpha][symbol][background][foreground]) do
  71. for xPos = 1, #groupedPicture[alpha][symbol][background][foreground][yPos] do
  72. imageX, imageY = x + groupedPicture[alpha][symbol][background][foreground][yPos][xPos] - 1, y + yPos - 1
  73.  
  74. if alpha > 0 then
  75. _, _, gpuGetBackground = gpu.get(imageX, imageY)
  76.  
  77. if alpha == 1 then
  78. currentBackground = gpuGetBackground
  79. gpu.setBackground(currentBackground)
  80. else
  81. currentBackground = color.blend(gpuGetBackground, background, alpha)
  82. gpu.setBackground(currentBackground)
  83. end
  84. end
  85.  
  86. gpu.set(imageX, imageY, symbol)
  87. end
  88. end
  89. end
  90. end
  91. end
  92. end
  93. end
  94. end
  95.  
  96. function image.create(width, height, background, foreground, alpha, symbol, random)
  97. local picture = {width, height, {}, {}, {}, {}}
  98.  
  99. for i = 1, width * height do
  100. table.insert(picture[3], random and math.random(0x0, 0xFFFFFF) or (background or 0x0))
  101. table.insert(picture[4], random and math.random(0x0, 0xFFFFFF) or (foreground or 0x0))
  102. table.insert(picture[5], alpha or 0x0)
  103. table.insert(picture[6], random and string.char(math.random(65, 90)) or (symbol or " "))
  104. end
  105.  
  106. return picture
  107. end
  108.  
  109. function image.copy(picture)
  110. local newPicture = {picture[1], picture[2], {}, {}, {}, {}}
  111.  
  112. for i = 1, #picture[3] do
  113. newPicture[3][i] = picture[3][i]
  114. newPicture[4][i] = picture[4][i]
  115. newPicture[5][i] = picture[5][i]
  116. newPicture[6][i] = picture[6][i]
  117. end
  118.  
  119. return newPicture
  120. end
  121.  
  122. -------------------------------------------------------------------------------
  123.  
  124. function image.loadFormatModule(path, extension)
  125. local success, result = loadfile(path)
  126. if success then
  127. success, result = pcall(success, image)
  128. if success then
  129. image.formatModules[extension] = result
  130. else
  131. error("Failed to execute image format module: " .. tostring(result))
  132. end
  133. else
  134. error("Failed to load image format module: " .. tostring(result))
  135. end
  136. end
  137.  
  138. local function loadOrSave(methodName, path, ...)
  139. local extension = fs.extension(path)
  140. if image.formatModules[extension] then
  141. local success, result = pcall(image.formatModules[extension][methodName], path, ...)
  142. if success then
  143. return result
  144. else
  145. return false, "Failed to " .. methodName .. " image file: " .. tostring(result)
  146. end
  147. else
  148. return false, "Failed to " .. methodName .. " image file: format module for extension \"" .. tostring(extension) .. "\" is not loaded"
  149. end
  150. end
  151.  
  152. function image.save(path, picture, encodingMethod)
  153. return loadOrSave("save", path, picture, encodingMethod)
  154. end
  155.  
  156. function image.load(path)
  157. return loadOrSave("load", path)
  158. end
  159.  
  160. -------------------------------------------------------------------------------
  161.  
  162. function image.toString(picture)
  163. local charArray = {
  164. string.format("%02X", picture[1]),
  165. string.format("%02X", picture[2])
  166. }
  167.  
  168. for i = 1, #picture[3] do
  169. table.insert(charArray, string.format("%02X", color.to8Bit(picture[3][i])))
  170. table.insert(charArray, string.format("%02X", color.to8Bit(picture[4][i])))
  171. table.insert(charArray, string.format("%02X", math.floor(picture[5][i] * 255)))
  172. table.insert(charArray, picture[6][i])
  173.  
  174. if i % 603 == 0 then
  175. computer.pullSignal(0)
  176. end
  177. end
  178.  
  179. return table.concat(charArray)
  180. end
  181.  
  182. function image.fromString(pictureString)
  183. local picture = {
  184. tonumber("0x" .. unicode.sub(pictureString, 1, 2)),
  185. tonumber("0x" .. unicode.sub(pictureString, 3, 4)),
  186. {}, {}, {}, {}
  187. }
  188.  
  189. for i = 5, unicode.len(pictureString), 7 do
  190. table.insert(picture[3], color.to24Bit(tonumber("0x" .. unicode.sub(pictureString, i, i + 1))))
  191. table.insert(picture[4], color.to24Bit(tonumber("0x" .. unicode.sub(pictureString, i + 2, i + 3))))
  192. table.insert(picture[5], tonumber("0x" .. unicode.sub(pictureString, i + 4, i + 5)) / 255)
  193. table.insert(picture[6], unicode.sub(pictureString, i + 6, i + 6))
  194. end
  195.  
  196. return picture
  197. end
  198.  
  199. -------------------------------------------------------------------------------
  200.  
  201. function image.set(picture, x, y, background, foreground, alpha, symbol)
  202. local index = image.getIndex(x, y, picture[1])
  203. picture[3][index], picture[4][index], picture[5][index], picture[6][index] = background, foreground, alpha, symbol
  204.  
  205. return picture
  206. end
  207.  
  208. function image.get(picture, x, y)
  209. local index = image.getIndex(x, y, picture[1])
  210. return picture[3][index], picture[4][index], picture[5][index], picture[6][index]
  211. end
  212.  
  213. function image.getSize(picture)
  214. return picture[1], picture[2]
  215. end
  216.  
  217. function image.getWidth(picture)
  218. return picture[1]
  219. end
  220.  
  221. function image.getHeight(picture)
  222. return picture[2]
  223. end
  224.  
  225. function image.transform(picture, newWidth, newHeight)
  226. local newPicture, stepWidth, stepHeight, background, foreground, alpha, symbol = {newWidth, newHeight, {}, {}, {}, {}}, picture[1] / newWidth, picture[2] / newHeight
  227.  
  228. local x, y = 1, 1
  229. for j = 1, newHeight do
  230. for i = 1, newWidth do
  231. background, foreground, alpha, symbol = image.get(picture, math.floor(x), math.floor(y))
  232. table.insert(newPicture[3], background)
  233. table.insert(newPicture[4], foreground)
  234. table.insert(newPicture[5], alpha)
  235. table.insert(newPicture[6], symbol)
  236.  
  237. x = x + stepWidth
  238. end
  239.  
  240. x, y = 1, y + stepHeight
  241. end
  242.  
  243. return newPicture
  244. end
  245.  
  246. function image.crop(picture, fromX, fromY, width, height)
  247. if fromX >= 1 and fromY >= 1 and fromX + width - 1 <= picture[1] and fromY + height - 1 <= picture[2] then
  248. local newPicture, background, foreground, alpha, symbol = {width, height, {}, {}, {}, {}}
  249.  
  250. for y = fromY, fromY + height - 1 do
  251. for x = fromX, fromX + width - 1 do
  252. background, foreground, alpha, symbol = image.get(picture, x, y)
  253. table.insert(newPicture[3], background)
  254. table.insert(newPicture[4], foreground)
  255. table.insert(newPicture[5], alpha)
  256. table.insert(newPicture[6], symbol)
  257. end
  258. end
  259.  
  260. return newPicture
  261. else
  262. return false, "Failed to crop image: target coordinates are out of source range"
  263. end
  264. end
  265.  
  266. function image.flipHorizontally(picture)
  267. local newPicture, background, foreground, alpha, symbol = {picture[1], picture[2], {}, {}, {}, {}}
  268.  
  269. for y = 1, picture[2] do
  270. for x = picture[1], 1, -1 do
  271. background, foreground, alpha, symbol = image.get(picture, x, y)
  272. table.insert(newPicture[3], background)
  273. table.insert(newPicture[4], foreground)
  274. table.insert(newPicture[5], alpha)
  275. table.insert(newPicture[6], symbol)
  276. end
  277. end
  278.  
  279. return newPicture
  280. end
  281.  
  282. function image.flipVertically(picture)
  283. local newPicture, background, foreground, alpha, symbol = {picture[1], picture[2], {}, {}, {}, {}}
  284.  
  285. for y = picture[2], 1, -1 do
  286. for x = 1, picture[1] do
  287. background, foreground, alpha, symbol = image.get(picture, x, y)
  288. table.insert(newPicture[3], background)
  289. table.insert(newPicture[4], foreground)
  290. table.insert(newPicture[5], alpha)
  291. table.insert(newPicture[6], symbol)
  292. end
  293. end
  294.  
  295. return newPicture
  296. end
  297.  
  298. function image.expand(picture, fromTop, fromBottom, fromLeft, fromRight, background, foreground, alpha, symbol)
  299. local newPicture = image.create(picture[1] + fromRight + fromLeft, picture[2] + fromTop + fromBottom, background, foreground, alpha, symbol)
  300.  
  301. for y = 1, picture[2] do
  302. for x = 1, picture[1] do
  303. image.set(newPicture, x + fromLeft, y + fromTop, image.get(picture, x, y))
  304. end
  305. end
  306.  
  307. return newPicture
  308. end
  309.  
  310. function image.blend(picture, blendColor, transparency)
  311. local newPicture = {picture[1], picture[2], {}, {}, {}, {}}
  312.  
  313. for i = 1, #picture[3] do
  314. table.insert(newPicture[3], color.blend(picture[3][i], blendColor, transparency))
  315. table.insert(newPicture[4], color.blend(picture[4][i], blendColor, transparency))
  316. table.insert(newPicture[5], picture[5][i])
  317. table.insert(newPicture[6], picture[6][i])
  318. end
  319.  
  320. return newPicture
  321. end
  322.  
  323. function image.rotate(picture, angle)
  324. local radAngle = math.rad(angle)
  325. local sin, cos = math.sin(radAngle), math.cos(radAngle)
  326. local pixMap = {}
  327.  
  328. local xCenter, yCenter = picture[1] / 2, picture[2] / 2
  329. local xMin, xMax, yMin, yMax = math.huge, -math.huge, math.huge, -math.huge
  330. for y = 1, picture[2] do
  331. for x = 1, picture[1] do
  332. local xNew = math.round(xCenter + (x - xCenter) * cos - (y - yCenter) * sin)
  333. local yNew = math.round(yCenter + (y - yCenter) * cos + (x - xCenter) * sin)
  334.  
  335. xMin, xMax, yMin, yMax = math.min(xMin, xNew), math.max(xMax, xNew), math.min(yMin, yNew), math.max(yMax, yNew)
  336.  
  337. pixMap[yNew] = pixMap[yNew] or {}
  338. pixMap[yNew][xNew] = {image.get(picture, x, y)}
  339. end
  340. end
  341.  
  342. local newPicture = image.create(xMax - xMin + 1, yMax - yMin + 1, 0xFF0000, 0x0, 0x0, "#")
  343. for y in pairs(pixMap) do
  344. for x in pairs(pixMap[y]) do
  345. image.set(newPicture, x - xMin + 1, y - yMin + 1, pixMap[y][x][1], pixMap[y][x][2], pixMap[y][x][3], pixMap[y][x][4])
  346. end
  347. end
  348.  
  349. return newPicture
  350. end
  351.  
  352. -------------------------------------------------------------------------------
  353.  
  354. image.loadFormatModule("/lib/FormatModules/OCIF.lua", ".pic")
  355.  
  356. -------------------------------------------------------------------------------
  357.  
  358. return image
Add Comment
Please, Sign In to add comment