07-26-2023, 02:25 PM
(This post was last modified: 07-26-2023, 02:26 PM by TerryRitchie.)
I modified RhoSigma's ApplyFilter& function from his Image Processing Library (imageprocess.bm) to only perform Gaussian blurs in the laser project I'm working on. Here is the result:
Code: (Select All)
' ______________________________________________________________________________________________________________________________________________
'/ \
FUNCTION ApplyGauss& (SourceHandle AS LONG) ' ApplyGauss& |
' __________________________________________________________________________________________________________________________________________|____
'/ \
'| Applies a Gaussian blur to the image passed in. |
'| |
'| BlurredImage = ApplyGauss&(OriginalImage) |
'| |
'| SourceHandle - the image to be blurred |
'| |
'| NOTE: This function is a modified version of RhoSigma's Image Processing Library's ApplyFilter& function found in imageprocess.bm. |
'| The function has been modified to only support the "gauss8" method of blurring with no optional parameters available. |
'| RhoSigma's unedited library can be obtained here: https://qb64phoenix.com/forum/showthread.php?tid=1033 |
'| Thanks to RhoSigma for offering this library. |
'\_______________________________________________________________________________________________________________________________________________/
DIM AS INTEGER SourceWidth, SourceHeight, FilterY, FilterX, y, x, NewAlpha, FilterWeight, NewRed, NewGreen, NewBlue, Size, Add, Div
DIM AS LONG NewHandle, SumRed, SumGreen, SumBlue
DIM AS _UNSIGNED LONG OriginalRGB, NewRGB
DIM AS _OFFSET PixelOffset, FilterOffset
DIM SourceBuffer AS _MEM
DIM NewBuffer AS _MEM
STATIC Weight(0 TO 6, 0 TO 6) AS INTEGER
'+---------------------+
'| Apply filter values |
'+---------------------+
Size = 3 ' set filter values for "gauss8"
Add = 0
Div = 16
IF Weight(2, 2) = 0 THEN
Weight(2, 2) = 1: Weight(2, 3) = 2: Weight(2, 4) = 1
Weight(3, 2) = 2: Weight(3, 3) = 4: Weight(3, 4) = 2
Weight(4, 2) = 1: Weight(4, 3) = 2: Weight(4, 4) = 1
END IF
ApplyGauss& = -1 ' assume handle is invalid
IF SourceHandle < -1 OR SourceHandle = 0 THEN ' valid source image handle?
IF _PIXELSIZE(SourceHandle) = 4 THEN ' yes, 32bit image?
'+-----------------------+
'| Copy the source image |
'+-----------------------+
SourceWidth = _WIDTH(SourceHandle) ' yes, get source image dimensions
SourceHeight = _HEIGHT(SourceHandle)
NewHandle = _NEWIMAGE(SourceWidth, SourceHeight, 32) ' create new image canvas of same size
_PUTIMAGE , SourceHandle, NewHandle ' copy source image
'+----------------------+
'| Process copied image |
'+----------------------+
$CHECKING:OFF
IF NewHandle < -1 THEN ' is handle valid?
Size = Size \ 2 ' yes, adjust filter size
'+------------------------------------+
'| Use direct memory access for speed |
'+------------------------------------+
SourceBuffer = _MEMIMAGE(SourceHandle) ' get image memory locations
NewBuffer = _MEMIMAGE(NewHandle)
'+-------------------------------------+
'| Iterate through source image pixels |
'+-------------------------------------+
y = -1 ' set y location
DO ' iterate vertically through source image
y = y + 1 ' increment y location
PixelOffset = (y * SourceWidth * 4) ' calculate pixel offset
x = -1 ' set x location
DO ' iterate horizontally through source image
x = x + 1 ' increment x location
_MEMGET SourceBuffer, SourceBuffer.OFFSET + PixelOffset, OriginalRGB ' get source image pixel
NewAlpha = _ALPHA32(OriginalRGB) ' record pixel's alpha value
SumRed = 0 ' clear previous summed pixel weight values
SumGreen = 0
SumBlue = 0
'+-------------------------------------------------------+
'| Iterate through neigboring pixels using filter matrix |
'+-------------------------------------------------------+
FilterY = y - Size - 1 ' calculate filter vertical start point
DO ' iterate vertically through filter matrix
FilterY = FilterY + 1 ' increment y location
FilterOffset = (FilterY * SourceWidth * 4) + ((x - Size) * 4) ' calculate filter offset
FilterX = x - Size - 1 ' calculate filter horizontal start point
DO ' iterate horizontally through filter matrix
FilterX = FilterX + 1 ' increment x location
IF FilterY >= 0 AND FilterY < SourceHeight AND FilterX >= 0 AND FilterX < SourceWidth THEN ' is position outside image?
_MEMGET SourceBuffer, SourceBuffer.OFFSET + FilterOffset, OriginalRGB ' no, get source image pixel
ELSE
_MEMGET SourceBuffer, SourceBuffer.OFFSET + PixelOffset, OriginalRGB ' yes, get center source image pixel
END IF
'+----------------------+
'| Sum up pixel weights |
'+----------------------+
FilterWeight = Weight(FilterY - y + 3, FilterX - x + 3) ' get weight value from filter array
SumRed = SumRed + (_RED32(OriginalRGB) * FilterWeight) ' apply weight value to RGB colors
SumGreen = SumGreen + (_GREEN32(OriginalRGB) * FilterWeight)
SumBlue = SumBlue + (_BLUE32(OriginalRGB) * FilterWeight)
FilterOffset = FilterOffset + 4 ' increment to next filter offset
LOOP UNTIL FilterX = x + Size
LOOP UNTIL FilterY = y + Size
NewRed = CINT(SumRed / Div) + Add ' calculate new pixel channel colors
NewGreen = CINT(SumGreen / Div) + Add
NewBlue = CINT(SumBlue / Div) + Add
NewRGB = _RGBA32(NewRed, NewGreen, NewBlue, NewAlpha) ' calculate new pixel color
_MEMPUT NewBuffer, NewBuffer.OFFSET + PixelOffset, NewRGB ' place new pixel color onto new image
PixelOffset = PixelOffset + 4 ' increment to next pixel offset
LOOP UNTIL x = SourceWidth - 1
LOOP UNTIL y = SourceHeight - 1
'+-----------------------------+
'| Free RAM then return result |
'+-----------------------------+
_MEMFREE NewBuffer ' remove image buffers from RAM
_MEMFREE SourceBuffer
ApplyGauss& = NewHandle ' return new image
END IF
$CHECKING:ON
END IF
END IF
END FUNCTION