Image lib convolution filter support

This commit is contained in:
IgorTimofeev
2021-07-16 19:21:22 +07:00
parent 2287ab1a08
commit 320489abe7
4 changed files with 99 additions and 47 deletions

View File

@@ -3,6 +3,7 @@ local GUI = require("GUI")
local system = require("System")
local keyboard = require("Keyboard")
local screen = require("Screen")
local text = require("Text")
---------------------------------------------------------------------------------
@@ -26,11 +27,15 @@ disp.draw = function(disp)
screen.drawText(x + unicode.len(text), y, 0x00A8FF, "")
end
window.addLine = function(line)
table.insert(lines, line)
window.addLine = function(value)
local value = text.wrap(value, disp.width)
if #lines - lineFrom + 1 > disp.height - 1 then
lineFrom = lineFrom + 1
for i = 1, #value do
table.insert(lines, value[i])
if #lines - lineFrom + 1 > disp.height - 1 then
lineFrom = lineFrom + 1
end
end
end

View File

@@ -677,21 +677,21 @@ editItem:addSeparator()
editItem:addItem(locale.gaussianBlur).onTouch = function()
local container = GUI.addBackgroundContainer(workspace, true, true, locale.gaussianBlur)
container.layout:setSpacing(1, 1, 2)
container.panel.eventHandler = nil
local radius = container.layout:addChild(GUI.slider(1, 1, 50, 0x66DB80, 0x0, 0xFFFFFF, 0xAAAAAA, 0, 5, 2.5, true, locale.radius))
local force = container.layout:addChild(GUI.slider(1, 1, 50, 0x66DB80, 0x0, 0xFFFFFF, 0xAAAAAA, 0, 1, 0.5, true, locale.force))
local radius = container.layout:addChild(GUI.slider(1, 1, 50, 0x66DB80, 0x0, 0xFFFFFF, 0xAAAAAA, 1, 10, 2, true, locale.radius))
radius.height = 2
radius.roundValues = true
local force = container.layout:addChild(GUI.slider(1, 1, 50, 0x66DB80, 0x0, 0xFFFFFF, 0xAAAAAA, 0, 1, 0.5, true, locale.force))
force.height = 2
local buttonsLay = container.layout:addChild(GUI.layout(1, 1, 30, 7, 1, 1))
buttonsLay:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.ok)).onTouch = function()
container.layout:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.ok)).onTouch = function()
window.image.data = image.convolve(window.image.data, image.getGaussianBlurKernel(math.floor(radius.value), force.value))
container:remove()
end
buttonsLay:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.cancel)).onTouch = function()
container.layout:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.cancel)).onTouch = function()
container:remove()
end
end

View File

@@ -566,18 +566,42 @@ function image.invert(picture)
return picture
end
function image.getGaussianBlurKernel(radius)
-- Todo
end
function image.getGaussianBlurKernel(radius, weight)
local size, index, sum, weightSquared2, value =
radius * 2 + 1,
2,
0,
2 * weight * weight
function image.convolve(picture, kernel)
-- Copying
local newPicture = {}
local kernel, constant =
{size},
1 / (math.pi * weightSquared2)
-- Filling convolution matrix
for y = -radius, radius do
for x = -radius, radius do
value = constant * math.exp(-((y * y) + (x * x)) / weightSquared2);
kernel[index] = value
sum = sum + value;
for i = 1, #picture do
newPicture[i] = picture[i]
index = index + 1
end
end
index = 2
for y = 1, size do
for x = 1, size do
kernel[index] = kernel[index] * 1 / sum;
index = index + 1
end
end
return kernel;
end
function image.convolve(picture, kernel, affectsForeground)
-- Processing
local
pictureWidth,
@@ -585,21 +609,23 @@ function image.convolve(picture, kernel)
kernelSize,
pictureIndex,
kernelIndex,
rAcc,
gAcc,
bAcc,
accCount,
kernelValue,
rAccB,
gAccB,
bAccB,
r,
g,
b,
cx,
cy = picture[1], picture[2], kernel[1], 3
local kernelRadius = math.floor(kernelSize / 2)
local newPicture, kernelRadius =
{ pictureWidth, pictureHeight },
math.floor(kernelSize / 2)
for y = 1, pictureHeight do
for x = 1, pictureWidth do
rAcc, gAcc, bAcc, kernelIndex, pictureIndex = 0, 0, 0, 2, pictureIndex + 1
rAccB, gAccB, bAccB, kernelIndex = 0, 0, 0, 2
-- Summing
for ky = -kernelRadius, kernelRadius do
@@ -607,13 +633,16 @@ function image.convolve(picture, kernel)
if cy >= 1 and cy <= pictureHeight then
for kx = -kernelRadius, kernelRadius do
cx = y + ky
kernelIndex = kernelIndex + 1
cx = x + kx
if cx >= 1 and cx <= pictureWidth then
r, g, b = color.integerToRGB(picture[pictureIndex])
rAcc, gAcc, bAcc = rAcc + r, gAcc + g, bAcc + b
kernelValue = kernel[kernelIndex]
r, g, b = color.integerToRGB(picture[4 * (pictureWidth * (cy - 1) + cx) - 1])
rAccB, gAccB, bAccB = rAccB + r * kernelValue, gAccB + g * kernelValue, bAccB + b * kernelValue
end
kernelIndex = kernelIndex + 1
end
else
kernelIndex = kernelIndex + kernelSize
@@ -621,32 +650,42 @@ function image.convolve(picture, kernel)
end
-- Cropping & rounding
if rAcc > 255 then
rAcc = 255
elseif rAcc < 0 then
rAcc = 0
if rAccB > 255 then
rAccB = 255
elseif rAccB < 0 then
rAccB = 0
else
rAcc = rAcc - rAcc % 1
rAccB = rAccB - rAccB % 1
end
if gAcc > 255 then
gAcc = 255
elseif gAcc < 0 then
gAcc = 0
if gAccB > 255 then
gAccB = 255
elseif gAccB < 0 then
gAccB = 0
else
gAcc = gAcc - gAcc % 1
gAccB = gAccB - gAccB % 1
end
if bAcc > 255 then
bAcc = 255
elseif bAcc < 0 then
bAcc = 0
if bAccB > 255 then
bAccB = 255
elseif bAccB < 0 then
bAccB = 0
else
bAcc = bAcc - bAcc % 1
bAccB = bAccB - bAccB % 1
end
-- Setting new pixel
newPicture[pictureIndex] = color.RGBToInteger(rAcc, gAcc, bAcc)
newPicture[pictureIndex] = color.RGBToInteger(rAccB, gAccB, bAccB)
pictureIndex = pictureIndex + 1
newPicture[pictureIndex] = 0x0
pictureIndex = pictureIndex + 1
newPicture[pictureIndex] = picture[pictureIndex]
pictureIndex = pictureIndex + 1
newPicture[pictureIndex] = " "
pictureIndex = pictureIndex + 1
end
end

View File

@@ -2924,10 +2924,18 @@ _G.print = function(...)
end
end
local args = {...}
local args, arg = {...}
for i = 1, #args do
args[i] = tostring(args[i])
arg = args[i]
if type(arg) == "table" then
arg = text.serialize(arg, true, " ", 3)
else
arg = tostring(arg)
end
args[i] = arg
end
args = table.concat(args, " ")