108 lines
3.4 KiB
Plaintext
108 lines
3.4 KiB
Plaintext
-- demo\rosetta\Image_convolution.exw
|
|
include pGUI.e
|
|
|
|
constant filters = {-- Emboss
|
|
{{-2.0, -1.0, 0.0},
|
|
{-1.0, 1.0, 1.0},
|
|
{ 0.0, 1.0, 2.0}},
|
|
-- Sharpen
|
|
{{-1.0, -1.0, -1.0},
|
|
{-1.0, 9.0, -1.0},
|
|
{-1.0, -1.0, -1.0}},
|
|
-- Sobel_emboss
|
|
{{-1.0, -2.0, -1.0},
|
|
{ 0.0, 0.0, 0.0},
|
|
{ 1.0, 2.0, 1.0}},
|
|
-- Box_blur
|
|
{{ 1.0, 1.0, 1.0},
|
|
{ 1.0, 1.0, 1.0},
|
|
{ 1.0, 1.0, 1.0}},
|
|
-- Gaussian_blur
|
|
{{1, 4, 7, 4, 1},
|
|
{4, 16, 26, 16, 4},
|
|
{7, 26, 41, 26, 7},
|
|
{4, 16, 26, 16, 4},
|
|
{1, 4, 7, 4, 1}}}
|
|
|
|
function convolute(imImage img, integer fdx)
|
|
integer width = im_width(img),
|
|
height = im_height(img)
|
|
sequence original = repeat(repeat(0,width),height),
|
|
new_image,
|
|
filter = filters[fdx]
|
|
integer fh = length(filter), hh=(fh-1)/2,
|
|
fw = length(filter[1]), hw=(fw-1)/2,
|
|
divisor = max(sum(filter),1)
|
|
|
|
for y=height-1 to 0 by -1 do
|
|
for x=0 to width-1 do
|
|
original[height-y,x+1] = im_pixel(img, x, y)
|
|
end for
|
|
end for
|
|
new_image = original
|
|
|
|
for y=hh+1 to height-hh-1 do
|
|
for x=hw+1 to width-hw-1 do
|
|
sequence newrgb = {0,0,0}
|
|
for i=-hh to +hh do
|
|
for j=-hw to +hw do
|
|
newrgb = sq_add(newrgb,sq_mul(filter[i+hh+1,j+hw+1],original[y+i,x+j]))
|
|
end for
|
|
end for
|
|
new_image[y,x] = sq_max(sq_min(sq_floor_div(newrgb,divisor),255),0)
|
|
end for
|
|
end for
|
|
|
|
new_image = flatten(new_image) -- (as needed by IupImageRGB)
|
|
Ihandle new_img = IupImageRGB(width, height, new_image)
|
|
return new_img
|
|
end function
|
|
|
|
IupOpen()
|
|
|
|
constant w = machine_word(),
|
|
TITLE = "Image convolution"
|
|
atom pError = allocate(w)
|
|
imImage im1 = imFileImageLoadBitmap("Quantum_frog.512.png",0,pError)
|
|
|
|
if im1=NULL then
|
|
?{"error opening image",peekNS(pError,w,1)}
|
|
{} = wait_key()
|
|
abort(0)
|
|
end if
|
|
|
|
Ihandle dlg,
|
|
filter = IupList("DROPDOWN=YES, VALUE=1")
|
|
|
|
Ihandln image1 = IupImageFromImImage(im1),
|
|
image2 = convolute(im1,1),
|
|
label1 = IupLabel(),
|
|
label2 = IupLabel()
|
|
IupSetAttributeHandle(label1, "IMAGE", image1)
|
|
IupSetAttributeHandle(label2, "IMAGE", image2)
|
|
|
|
function valuechanged_cb(Ihandle /*filter*/)
|
|
IupSetAttribute(dlg,"TITLE","Working...")
|
|
IupSetAttributeHandle(label2, "IMAGE", NULL)
|
|
IupDestroy(image2)
|
|
image2 = convolute(im1,IupGetInt(filter,"VALUE"))
|
|
IupSetAttributeHandle(label2, "IMAGE", image2)
|
|
IupSetAttribute(dlg,"TITLE",TITLE)
|
|
IupRefresh(dlg)
|
|
return IUP_DEFAULT
|
|
end function
|
|
IupSetCallback(filter,"VALUECHANGED_CB",Icallback("valuechanged_cb"))
|
|
|
|
IupSetAttributes(filter,"1=Emboss, 2=Sharpen, 3=\"Sobel emboss\", 4=\"Box_blur\", 5=Gaussian_blur")
|
|
IupSetAttributes(filter,"VISIBLEITEMS=6") -- (still dunno why this trick works)
|
|
dlg = IupDialog(IupVbox({filter,
|
|
IupFill(),
|
|
IupHbox({IupFill(),label1, label2,IupFill()}),
|
|
IupFill()}))
|
|
IupSetAttribute(dlg, "TITLE", TITLE)
|
|
IupCloseOnEscape(dlg)
|
|
IupShow(dlg)
|
|
|
|
IupMainLoop()
|
|
IupClose()
|