Part 2/2
Code:
Procedure.i ImageFilter_weight(*this.IImageFilter, *image.IImageFilter, factor.f = 1, delta.i = 0)
Protected *object.OImageFilter
Protected *src.ImageFilter_RGBA, *dest.ImageFilter_RGBA
Protected s.i, d.i
Protected int.i
If *this = #Null Or *image = #Null
ProcedureReturn #False
EndIf
*object = *this
If *object\width <> *image\getWidth() Or *object\height <> *image\getHeight()
ProcedureReturn #False
EndIf
*src = *image\getImageMem()
*dest = *object\srcMem
For i = 0 To *object\pixels - 1
For channel = 0 To #IF_UsedChannels - 1
s = (*src\channel[channel] & $FF)
d = (*dest\channel[channel] & $FF)
If s > 0
int = Int((factor * d * 255 / s) + delta)
Else
int = 0
EndIf
limit(int, 0, $FF)
*dest\channel[channel] = int
Next
*src + SizeOf(ImageFilter_RGBA)
*dest + SizeOf(ImageFilter_RGBA)
Next
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_weightMask(*this.IImageFilter, *image.IImageFilter, *mask.IImageFilter, factor.f = 1, delta.i = 0)
Protected *object.OImageFilter
Protected *src.ImageFilter_RGBA, *msk.ImageFilter_RGBA, *dest.ImageFilter_RGBA
Protected s.i, m.i, d.i
Protected int.i
If *this = #Null Or *image = #Null Or *mask = #Null
ProcedureReturn #False
EndIf
*object = *this
If *object\width <> *image\getWidth() Or *object\height <> *image\getHeight() Or *object\width <> *mask\getWidth() Or *object\height <> *mask\getHeight()
ProcedureReturn #False
EndIf
*src = *image\getImageMem()
*msk = *mask\getImageMem()
*dest = *object\srcMem
For i = 0 To *object\pixels - 1
For channel = 0 To #IF_UsedChannels - 1
s = (*src\channel[channel] & $FF)
m = (*msk\channel[channel] & $FF)
d = (*dest\channel[channel] & $FF)
int = Int((((d * ($FF - m)) + (s * m)) * factor / $FF) + delta)
limit(int, 0, $FF)
*dest\channel[channel] = int
Next
*src + SizeOf(ImageFilter_RGBA)
*msk + SizeOf(ImageFilter_RGBA)
*dest + SizeOf(ImageFilter_RGBA)
Next
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_difference(*this.IImageFilter, *image.IImageFilter, factor.f = 1, delta.i = 0)
Protected *object.OImageFilter
Protected *src.ImageFilter_RGBA, *dest.ImageFilter_RGBA
Protected s.i, d.i
Protected int.i
If *this = #Null Or *image = #Null
ProcedureReturn #False
EndIf
*object = *this
If *object\width <> *image\getWidth() Or *object\height <> *image\getHeight()
ProcedureReturn #False
EndIf
*src = *image\getImageMem()
*dest = *object\srcMem
For i = 0 To *object\pixels - 1
For channel = 0 To #IF_UsedChannels - 1
s = (*src\channel[channel] & $FF)
d = (*dest\channel[channel] & $FF)
int = Int((factor * Abs(d - s)) + delta)
limit(int, 0, $FF)
*dest\channel[channel] = int
Next
*src + SizeOf(ImageFilter_RGBA)
*dest + SizeOf(ImageFilter_RGBA)
Next
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_euclidianNorm(*this.IImageFilter, *image.IImageFilter, offset.i)
Protected *object.OImageFilter
Protected *src.ImageFilter_RGBA, *dest.ImageFilter_RGBA
Protected s.i, d.i
Protected int.i
If *this = #Null Or *image = #Null
ProcedureReturn #False
EndIf
*object = *this
If *object\width <> *image\getWidth() Or *object\height <> *image\getHeight()
ProcedureReturn #False
EndIf
*src = *image\getImageMem()
*dest = *object\srcMem
For i = 0 To *object\pixels - 1
For channel = 0 To #IF_UsedChannels - 1
s = (*src\channel[channel] & $FF)
d = (*dest\channel[channel] & $FF)
int = Int(Sqr(Square(d - offset) + Square(s - offset)) + offset)
limit(int, 0, $FF)
*dest\channel[channel] = int
Next
*src + SizeOf(ImageFilter_RGBA)
*dest + SizeOf(ImageFilter_RGBA)
Next
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_manhattenNorm(*this.IImageFilter, *image.IImageFilter, offset.i)
Protected *object.OImageFilter
Protected *src.ImageFilter_RGBA, *dest.ImageFilter_RGBA
Protected s.i, d.i
Protected int.i
If *this = #Null Or *image = #Null
ProcedureReturn #False
EndIf
*object = *this
If *object\width <> *image\getWidth() Or *object\height <> *image\getHeight()
ProcedureReturn #False
EndIf
*src = *image\getImageMem()
*dest = *object\srcMem
For i = 0 To *object\pixels - 1
For channel = 0 To #IF_UsedChannels - 1
s = (*src\channel[channel] & $FF)
d = (*dest\channel[channel] & $FF)
int = Int(Abs(d - offset) + Abs(s - offset) + offset)
limit(int, 0, $FF)
*dest\channel[channel] = int
Next
*src + SizeOf(ImageFilter_RGBA)
*dest + SizeOf(ImageFilter_RGBA)
Next
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_addColorOverlay(*this.IImageFilter, color.i, opacity.f)
Protected *object.OImageFilter, dest.ImageFilter_RGBA
Protected *src.ImageFilter_RGBA
Protected int1.i, int2.i
If *this = #Null
ProcedureReturn #False
EndIf
*object = *this
If opacity < 0 Or opacity > 1
ProcedureReturn #False
EndIf
dest\rgba = color
*src = *object\srcMem
For i = 0 To *object\pixels - 1
For channel = 0 To #IF_UsedChannels - 1
int1 = *src\channel[channel] & $FF
int2 = dest\channel[channel] & $FF
int1 = Int((int1 * (1 - opacity)) + (int2 * opacity))
limit(int1, 0, $FF)
*src\channel[channel] = int1
Next channel
*src + SizeOf(ImageFilter_RGBA)
Next i
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_removeColorOverlay(*this.IImageFilter, color.i, opacity.f)
Protected *object.OImageFilter, dest.ImageFilter_RGBA
Protected *src.ImageFilter_RGBA
Protected int1.i, int2.i
If *this = #Null
ProcedureReturn #False
EndIf
*object = *this
If opacity <= 0 Or opacity >= 1
ProcedureReturn #False
EndIf
dest\rgba = color
*src = *object\srcMem
For i = 0 To *object\pixels - 1
For channel = 0 To #IF_UsedChannels - 1
int1 = *src\channel[channel] & $FF
int2 = dest\channel[channel] & $FF
int1 = Int(((int2 * opacity) - int1) / (opacity - 1))
limit(int1, 0, $FF)
*src\channel[channel] = int1
Next channel
*src + SizeOf(ImageFilter_RGBA)
Next i
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_median(*this.IImageFilter, size.i)
Protected *object.OImageFilter, src.ImageFilter_RGBA, *dest.ImageFilter_RGBA, *destMem.ImageFilter_RGBA
Protected Dim radix.i(255), half.i, median.i, index.i
If *this = #Null Or size < 1
ProcedureReturn #False
EndIf
*object = *this
half = ((size * 2 + 1) * (size * 2 + 1)) >> 1
*destMem = AllocateMemory(*object\pixels * SizeOf(ImageFilter_RGBA))
If *destMem = #Null
ProcedureReturn #False
EndIf
*dest = *destMem
For y = 0 To *object\height - 1
For x = 0 To *object\width - 1
For channel = 0 To #IF_UsedChannels - 1
For yi = y - size To y + size
For xi = x - size To x + size
If xi > 0 And yi > 0 And xi < *object\width And yi < *object\height
src\rgba = getColorFromArray(*object\srcMem, xi, yi, *object\width)
radix(src\channel[channel] & $FF) + 1
EndIf
Next xi
Next yi
median = 0
index = 255
For i = 0 To 255
median + radix(i)
radix(i) = 0
If median >= half
index = i
For j = i + 1 To 255
radix(j) = 0
Next j
Break 1
EndIf
Next i
*dest\channel[channel] = index
Next channel
*dest + SizeOf(ImageFilter_RGBA)
Next x
Next y
FreeMemory(*object\srcMem)
*object\srcMem = *destMem
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_nearMedian(*this.IImageFilter, normalSize.i, nearSize.i)
Protected *object.OImageFilter, src.ImageFilter_RGBA, *dest.ImageFilter_RGBA, *destMem.ImageFilter_RGBA
Protected Dim radix.i(255), half.i, median.i, index.i
Protected dif.i, minDif.i, minDifColor.ImageFilter_RGBA, int1.i, int2.i
If *this = #Null Or normalSize < 1 Or nearSize < 1
ProcedureReturn #False
EndIf
*object = *this
half = ((normalSize * 2 + 1) * (normalSize * 2 + 1)) >> 1
*destMem = AllocateMemory(*object\pixels * SizeOf(ImageFilter_RGBA))
If *destMem = #Null
ProcedureReturn #False
EndIf
*dest = *destMem
For y = 0 To *object\height - 1
For x = 0 To *object\width - 1
For channel = 0 To #IF_UsedChannels - 1
For yi = y - normalSize To y + normalSize
For xi = x - normalSize To x + normalSize
If xi > 0 And yi > 0 And xi < *object\width And yi < *object\height
src\rgba = getColorFromArray(*object\srcMem, xi, yi, *object\width)
radix(src\channel[channel] & $FF) + 1
EndIf
Next xi
Next yi
median = 0
index = 255
For i = 0 To 255
median + radix(i)
radix(i) = 0
If median >= half
index = i
For j = i + 1 To 255
radix(j) = 0
Next j
Break 1
EndIf
Next i
*dest\channel[channel] = index
Next channel
minDif = $300
minDifColor\rgba = *dest\rgba
For yi = y - nearSize To y + nearSize
For xi = x - nearSize To x + nearSize
If xi > 0 And yi > 0 And xi < *object\width And yi < *object\height
src\rgba = getColorFromArray(*object\srcMem, xi, yi, *object\width)
dif = 0
For channel = 0 To #IF_UsedChannels - 1
int1 = src\channel[channel] & $FF
int2 = *dest\channel[channel] & $FF
dif + Abs(int1 - int2)
Next channel
If dif < minDif
minDif = dif
minDifColor\rgba = src\rgba
EndIf
EndIf
Next xi
Next yi
*dest\rgba = minDifColor\rgba
*dest + SizeOf(ImageFilter_RGBA)
Next x
Next y
FreeMemory(*object\srcMem)
*object\srcMem = *destMem
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_binomial(*this.IImageFilter, size.i)
Protected *object.OImageFilter, *destMem.ImageFilter_RGBA
If *this = #Null Or size < 2
ProcedureReturn #False
EndIf
*object = *this
*destMem = *this\memBinomial(*object\srcMem, size)
If *destMem
FreeMemory(*object\srcMem)
*object\srcMem = *destMem
EndIf
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_minMax(*this.IImageFilter, size.i)
Protected *object.OImageFilter, src.ImageFilter_RGBA, *dest.ImageFilter_RGBA, *destMem.ImageFilter_RGBA
Protected Dim radix.i(255), min.i, max.i
If *this = #Null Or size < 1
ProcedureReturn #False
EndIf
*object = *this
*destMem = AllocateMemory(*object\pixels * SizeOf(ImageFilter_RGBA))
If *destMem = #Null
ProcedureReturn #False
EndIf
*dest = *destMem
For y = 0 To *object\height - 1
For x = 0 To *object\width - 1
For channel = 0 To #IF_UsedChannels - 1
For yi = y - size To y + size
For xi = x - size To x + size
If xi > 0 And yi > 0 And xi < *object\width And yi < *object\height
src\rgba = getColorFromArray(*object\srcMem, xi, yi, *object\width)
radix(src\channel[channel] & $FF) + 1
EndIf
Next xi
Next yi
min = -1
max = -1
For i = 0 To 255
If radix(i) = 0
If max = -1
min = i
EndIf
Else
max = i
EndIf
radix(i) = 0
Next i
*dest\channel[channel] = max - min - 1
Next channel
*dest + SizeOf(ImageFilter_RGBA)
Next x
Next y
FreeMemory(*object\srcMem)
*object\srcMem = *destMem
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_DoG(*this.IImageFilter, q.i, p.i)
Protected *object.OImageFilter, *qMem.ImageFilter_RGBA, *pMem.ImageFilter_RGBA
Protected *src.ImageFilter_RGBA, *q.ImageFilter_RGBA, *p.ImageFilter_RGBA
Protected int.i
If *this = #Null Or p < 1 Or p < 1
ProcedureReturn #False
EndIf
*object = *this
*pMem = *this\memBinomial(*object\srcMem, p)
If *pMem = #Null
ProcedureReturn #False
EndIf
*qMem = *this\memBinomial(*pMem, q)
If *qMem = #Null
FreeMemory(*pMem)
ProcedureReturn #False
EndIf
*src = *object\srcMem
*p = *pMem
*q = *qMem
For y = 0 To *object\height - 1
For x = 0 To *object\width - 1
For channel = 0 To #IF_UsedChannels - 1
int = (4 * ((*q\channel[channel] & $FF) - (*p\channel[channel] & $FF))) + 128
limit(int, 0, $FF)
*src\channel[channel] = int
Next
*src + SizeOf(ImageFilter_RGBA)
*p + SizeOf(ImageFilter_RGBA)
*q + SizeOf(ImageFilter_RGBA)
Next
Next
FreeMemory(*pMem)
FreeMemory(*qMem)
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_houghTransformation(*this.IImageFilter, threshold.i)
Protected *object.OImageFilter, *src.ImageFilter_RGBA, int.i
Protected *dest.ImageFilter_RGBA, *destMem.ImageFilter_RGBA
Protected halfWidth.i, halfHeight.i, imgId.i
If *this = #Null
ProcedureReturn #False
EndIf
*object = *this
halfWidth = *object\width >> 1
halfHeight = *object\height >> 1
limit(threshold, 0, $FF)
Protected width.i, height.i, thetaCos.i, d.i
width = 360 ;degree
height = Int(Sqr((halfWidth * halfWidth) + (halfHeight * halfHeight))) ;diagonal
*destMem = AllocateMemory(width * height * SizeOf(ImageFilter_RGBA))
If *destMem = #Null
ProcedureReturn #False
EndIf
Protected Dim thetaSin.f(360 + 90 - 1)
Protected Dim houghField.i(width - 1, height - 1, #IF_UsedChannels - 1)
Protected Dim maxValue.i(#IF_UsedChannels - 1)
For theta = 0 To 360 + 90 - 1
thetaSin(theta) = Sin(theta * 0.017453292519943295)
Next theta
*src = *object\srcMem
For y = 0 To *object\height - 1
For x = 0 To *object\width - 1
For theta = 0 To 360 - 1
d = Int(Abs(((y - halfHeight) * thetaSin(theta)) + ((x - halfWidth) * thetaSin(theta + 90))))
If d >= 0 And d < height
For channel = 0 To #IF_UsedChannels - 1
int = *src\channel[channel] & $FF
If int >= threshold
houghField(theta, d, channel) + int
EndIf
Next channel
EndIf
Next theta
*src + SizeOf(ImageFilter_RGBA)
Next x
Next y
For channel = 0 To #IF_UsedChannels - 1
maxValue(channel) = 1
Next channel
For y = 0 To height - 1
For x = 0 To width - 1
For channel = 0 To #IF_UsedChannels - 1
If houghField(x, y, channel) > maxValue(channel)
maxValue(channel) = houghField(x, y, channel)
EndIf
Next channel
Next x
Next y
imgId = CreateImage(#PB_Any, width, height, #IF_ImageDepth)
If IsImage(imgId) = #Null
ProcedureReturn #False
EndIf
If IsImage(*object\image)
FreeImage(*object\image)
EndIf
FreeMemory(*object\srcMem)
*object\image = imgId
*object\width = width
*object\height = height
*dest = *destMem
For y = 0 To height - 1
For x = 0 To width - 1
For channel = 0 To #IF_UsedChannels - 1
int = Int(houghField(x, y, channel) / maxValue(channel) * 255)
limit(int, 0, $FF)
*dest\channel[channel] = int
Next channel
*dest + SizeOf(ImageFilter_RGBA)
Next x
Next y
*object\srcMem = *destMem
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_threshold(*this.IImageFilter, value.i, keepColor.i = #False)
Protected *object.OImageFilter, gray.i, *src.ImageFilter_RGBA
If *this = #Null
ProcedureReturn #False
EndIf
*object = *this
*src = *object\srcMem
If keepColor
For i = 0 To *object\pixels - 1
gray = Gray(*src\rgba)
If gray < value
*src\rgba = $000000
Else
*src\rgba = RGB(gray, gray, gray)
EndIf
*src + SizeOf(ImageFilter_RGBA)
Next i
Else
For i = 0 To *object\pixels - 1
gray = Gray(*src\rgba)
If gray < value
*src\rgba = $000000
Else
*src\rgba = $FFFFFF
EndIf
*src + SizeOf(ImageFilter_RGBA)
Next i
EndIf
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_regionGrowing(*this.IImageFilter, x.i, y.i, maxDelta.i)
Protected *object.OImageFilter, rgb.ImageFilter_RGBA, *src.ImageFilter_RGBA
Protected *maskMem.ImageFilter_RGBA, *mask.ImageFilter_RGBA
Protected c1.ImageFilter_RGBA, c2.ImageFilter_RGBA
Protected NewList stack.POINT()
If *this = #Null Or x < 0 Or y < 0 Or maxDelta < 0 Or maxDelta > $FF
ProcedureReturn #False
EndIf
*object = *this
If x >= *object\width Or y >= *object\height
ProcedureReturn #False
EndIf
*maskMem = AllocateMemory(*object\pixels * SizeOf(ImageFilter_RGBA))
If *maskMem = 0
ProcedureReturn #False
EndIf
y = *object\height - y - 1
AddElement(stack())
stack()\x = x
stack()\y = y
setColorFromArray(*maskMem, x, y, *object\width, $FFFFFF)
While ListSize(stack()) > 0
FirstElement(stack())
sx = stack()\x
sy = stack()\y
DeleteElement(stack())
For yi = sy - 1 To sy + 1
If yi >= 0 And yi < *object\height
For xi = sx - 1 To sx + 1
If xi >= 0 And xi < *object\width
For yb = yi - 1 To yi + 1
If yb >= 0 And yb < *object\height
For xb = xi - 1 To xi + 1
If xb >= 0 And xb < *object\width
If getColorFromArray(*maskMem, xb, yb, *object\width) <> 0 And getColorFromArray(*maskMem, xi, yi, *object\width) = 0
delta = 0
c1\rgba = getColorFromArray(*object\srcMem, xb, yb, *object\width)
c2\rgba = getColorFromArray(*object\srcMem, xi, yi, *object\width)
If Abs(Red(c1\rgba) - Red(c2\rgba)) + Abs(Green(c1\rgba) - Green(c2\rgba)) + Abs(Blue(c1\rgba) - Blue(c2\rgba)) <= maxDelta
AddElement(stack())
stack()\x = xi
stack()\y = yi
setColorFromArray(*maskMem, xi, yi, *object\width, $FFFFFF)
Break 2
EndIf
EndIf
EndIf
Next xb
EndIf
Next yb
EndIf
Next xi
EndIf
Next yi
Wend
FreeMemory(*object\srcMem)
*object\srcMem = *maskMem
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_dilate(*this.IImageFilter, label.i, mask$, times.i)
Protected *object.OImageFilter, *destMem.ImageFilter_RGBA
Protected maskWidth.i, maskHeight.i, maskValues.i
Protected maskOffsetX.i, maskOffsetY.i
Protected oldValue.i, maskValue.i
Protected continueFor.i
Protected modified.i = #False
If *this = #Null Or times < 1 Or mask$ = ""
ProcedureReturn #False
EndIf
*object = *this
maskWidth = CountString(StringField(mask$, 1, "|"), ",") + 1
maskHeight = CountString(mask$, "|") + 1
Protected Dim mask.i((maskWidth * maskHeight) - 1)
maskValues = 0
For x = 0 To maskWidth - 1
For y = 0 To maskHeight - 1
If Val(Trim(StringField(StringField(mask$, y + 1, "|"), x + 1, ",")))
mask(maskValues) = ((y - (maskHeight / 2)) * *object\width) + x - (maskWidth / 2)
maskValues + 1
EndIf
Next
Next
maskOffsetX = maskWidth >> 1
maskOffsetY = maskHeight >> 1
*destMem = AllocateMemory(*object\pixels * SizeOf(ImageFilter_RGBA))
If *destMem = 0
ProcedureReturn #False
EndIf
For t = 1 To times
CopyMemory(*object\srcMem, *destMem, *object\pixels * SizeOf(ImageFilter_RGBA))
For x = maskOffsetX To *object\width - maskOffsetX - 1
For y = maskOffsetY To *object\height - maskOffsetY - 1
oldValue = getColorFromArray(*object\srcMem, x, y, *object\width)
continueFor = #False
For i = 0 To maskValues - 1
maskValue = getColorFromArray(*object\srcMem, x + mask(i), y, *object\width)
If maskValue = label
If oldValue <> label
setColorFromArray(*destMem, x, y, *object\width, label)
modified = #True
EndIf
continueFor = #True
Break 1
EndIf
Next i
If oldValue = label And continueFor = #False
setColorFromArray(*destMem, x, y, *object\width, $FFFFFF ! label)
modified = #True
EndIf
Next y
Next x
Swap *destMem, *object\srcMem
Next t
FreeMemory(*destMem)
ProcedureReturn modified
EndProcedure
Procedure.i ImageFilter_erode(*this.IImageFilter, label.i, mask$, times.i)
Protected *object.OImageFilter, *destMem.ImageFilter_RGBA
Protected maskWidth.i, maskHeight.i, maskValues.i
Protected maskOffsetX.i, maskOffsetY.i
Protected oldValue.i, maskValue.i
Protected continueFor.i
Protected modified.i = #False
If *this = #Null Or times < 1 Or mask$ = ""
ProcedureReturn #False
EndIf
*object = *this
maskWidth = CountString(StringField(mask$, 1, "|"), ",") + 1
maskHeight = CountString(mask$, "|") + 1
Protected Dim mask.i((maskWidth * maskHeight) - 1)
maskValues = 0
For x = 0 To maskWidth - 1
For y = 0 To maskHeight - 1
If Val(Trim(StringField(StringField(mask$, y + 1, "|"), x + 1, ",")))
mask(maskValues) = ((y - (maskHeight / 2)) * *object\width) + x - (maskWidth / 2)
maskValues + 1
EndIf
Next
Next
maskOffsetX = maskWidth >> 1
maskOffsetY = maskHeight >> 1
*destMem = AllocateMemory(*object\pixels * SizeOf(ImageFilter_RGBA))
If *destMem = 0
ProcedureReturn #False
EndIf
For t = 1 To times
CopyMemory(*object\srcMem, *destMem, *object\pixels * SizeOf(ImageFilter_RGBA))
For x = maskOffsetX To *object\width - maskOffsetX - 1
For y = maskOffsetY To *object\height - maskOffsetY - 1
oldValue = getColorFromArray(*object\srcMem, x, y, *object\width)
continueFor = #False
For i = 0 To maskValues - 1
maskValue = getColorFromArray(*object\srcMem, x + mask(i), y, *object\width)
If maskValue <> label
If oldValue = label
setColorFromArray(*destMem, x, y, *object\width, $FFFFFF ! label)
modified = #True
EndIf
continueFor = #True
Break 1
EndIf
Next i
If oldValue = label And continueFor = #False
setColorFromArray(*destMem, x, y, *object\width, label)
modified = #True
EndIf
Next y
Next x
Swap *destMem, *object\srcMem
Next t
FreeMemory(*destMem)
ProcedureReturn modified
EndProcedure
Procedure.i ImageFilter_closing(*this.IImageFilter, label.i, mask$, times.i)
Protected *object.OImageFilter, *destMem.ImageFilter_RGBA
Protected maskWidth.i, maskHeight.i, maskValues.i
Protected maskOffsetX.i, maskOffsetY.i
Protected oldValue.i, maskValue.i
Protected continueFor.i
Protected modified.i = #False
If *this = #Null Or times < 1 Or mask$ = ""
ProcedureReturn #False
EndIf
*object = *this
maskWidth = CountString(StringField(mask$, 1, "|"), ",") + 1
maskHeight = CountString(mask$, "|") + 1
Protected Dim mask.i((maskWidth * maskHeight) - 1)
maskValues = 0
For x = 0 To maskWidth - 1
For y = 0 To maskHeight - 1
If Val(Trim(StringField(StringField(mask$, y + 1, "|"), x + 1, ",")))
mask(maskValues) = ((y - (maskHeight / 2)) * *object\width) + x - (maskWidth / 2)
maskValues + 1
EndIf
Next
Next
maskOffsetX = maskWidth >> 1
maskOffsetY = maskHeight >> 1
*destMem = AllocateMemory(*object\pixels * SizeOf(ImageFilter_RGBA))
If *destMem = 0
ProcedureReturn #False
EndIf
For t = 1 To times
CopyMemory(*object\srcMem, *destMem, *object\pixels * SizeOf(ImageFilter_RGBA))
For x = maskOffsetX To *object\width - maskOffsetX - 1
For y = maskOffsetY To *object\height - maskOffsetY - 1
oldValue = getColorFromArray(*object\srcMem, x, y, *object\width)
continueFor = #False
For i = 0 To maskValues - 1
maskValue = getColorFromArray(*object\srcMem, x + mask(i), y, *object\width)
If maskValue = label
If oldValue <> label
setColorFromArray(*destMem, x, y, *object\width, label)
modified = #True
EndIf
continueFor = #True
Break 1
EndIf
Next i
If oldValue = label And continueFor = #False
setColorFromArray(*destMem, x, y, *object\width, $FFFFFF ! label)
modified = #True
EndIf
Next y
Next x
Swap *destMem, *object\srcMem
Next t
For t = 1 To times
CopyMemory(*object\srcMem, *destMem, *object\pixels * SizeOf(ImageFilter_RGBA))
For x = maskOffsetX To *object\width - maskOffsetX - 1
For y = maskOffsetY To *object\height - maskOffsetY - 1
oldValue = getColorFromArray(*object\srcMem, x, y, *object\width)
continueFor = #False
For i = 0 To maskValues - 1
maskValue = getColorFromArray(*object\srcMem, x + mask(i), y, *object\width)
If maskValue <> label
If oldValue = label
setColorFromArray(*destMem, x, y, *object\width, $FFFFFF ! label)
modified = #True
EndIf
continueFor = #True
Break 1
EndIf
Next i
If oldValue = label And continueFor = #False
setColorFromArray(*destMem, x, y, *object\width, label)
modified = #True
EndIf
Next y
Next x
Swap *destMem, *object\srcMem
Next t
FreeMemory(*destMem)
ProcedureReturn modified
EndProcedure
Procedure.i ImageFilter_opening(*this.IImageFilter, label.i, mask$, times.i)
Protected *object.OImageFilter, *destMem.ImageFilter_RGBA
Protected maskWidth.i, maskHeight.i, maskValues.i
Protected maskOffsetX.i, maskOffsetY.i
Protected oldValue.i, maskValue.i
Protected continueFor.i
Protected modified.i = #False
If *this = #Null Or times < 1 Or mask$ = ""
ProcedureReturn #False
EndIf
*object = *this
maskWidth = CountString(StringField(mask$, 1, "|"), ",") + 1
maskHeight = CountString(mask$, "|") + 1
Protected Dim mask.i((maskWidth * maskHeight) - 1)
maskValues = 0
For x = 0 To maskWidth - 1
For y = 0 To maskHeight - 1
If Val(Trim(StringField(StringField(mask$, y + 1, "|"), x + 1, ",")))
mask(maskValues) = ((y - (maskHeight / 2)) * *object\width) + x - (maskWidth / 2)
maskValues + 1
EndIf
Next
Next
maskOffsetX = maskWidth >> 1
maskOffsetY = maskHeight >> 1
*destMem = AllocateMemory(*object\pixels * SizeOf(ImageFilter_RGBA))
If *destMem = 0
ProcedureReturn #False
EndIf
For t = 1 To times
CopyMemory(*object\srcMem, *destMem, *object\pixels * SizeOf(ImageFilter_RGBA))
For x = maskOffsetX To *object\width - maskOffsetX - 1
For y = maskOffsetY To *object\height - maskOffsetY - 1
oldValue = getColorFromArray(*object\srcMem, x, y, *object\width)
continueFor = #False
For i = 0 To maskValues - 1
maskValue = getColorFromArray(*object\srcMem, x + mask(i), y, *object\width)
If maskValue <> label
If oldValue = label
setColorFromArray(*destMem, x, y, *object\width, $FFFFFF ! label)
modified = #True
EndIf
continueFor = #True
Break 1
EndIf
Next i
If oldValue = label And continueFor = #False
setColorFromArray(*destMem, x, y, *object\width, label)
modified = #True
EndIf
Next y
Next x
Swap *destMem, *object\srcMem
Next t
For t = 1 To times
CopyMemory(*object\srcMem, *destMem, *object\pixels * SizeOf(ImageFilter_RGBA))
For x = maskOffsetX To *object\width - maskOffsetX - 1
For y = maskOffsetY To *object\height - maskOffsetY - 1
oldValue = getColorFromArray(*object\srcMem, x, y, *object\width)
continueFor = #False
For i = 0 To maskValues - 1
maskValue = getColorFromArray(*object\srcMem, x + mask(i), y, *object\width)
If maskValue = label
If oldValue <> label
setColorFromArray(*destMem, x, y, *object\width, label)
modified = #True
EndIf
continueFor = #True
Break 1
EndIf
Next i
If oldValue = label And continueFor = #False
setColorFromArray(*destMem, x, y, *object\width, $FFFFFF ! label)
modified = #True
EndIf
Next y
Next x
Swap *destMem, *object\srcMem
Next t
FreeMemory(*destMem)
ProcedureReturn modified
EndProcedure
Procedure.i ImageFilter_thin(*this.IImageFilter, label.i, times.i)
Protected *object.OImageFilter, *destMem.ImageFilter_RGBA, *tmpMem.ImageFilter_RGBA
Protected Dim indexedFilterMask.i(7)
Protected Dim neighbors.i(7)
Protected numNeighbors.i, numTransitions.i
Protected modified.i = #False
If *this = #Null
ProcedureReturn #False
EndIf
*object = *this
*destMem = AllocateMemory(*object\pixels * SizeOf(ImageFilter_RGBA))
If *destMem = 0
ProcedureReturn #False
EndIf
indexedFilterMask(0) = -*object\width
indexedFilterMask(1) = -*object\width + 1
indexedFilterMask(2) = 1
indexedFilterMask(3) = *object\width + 1
indexedFilterMask(4) = *object\width
indexedFilterMask(5) = *object\width - 1
indexedFilterMask(6) = -1
indexedFilterMask(7) = -*object\width - 1
For t = 1 To times
CopyMemory(*object\srcMem, *destMem, *object\pixels * SizeOf(ImageFilter_RGBA))
For y = 1 To *object\height - 2
For x = 1 To *object\width - 2
If getColorFromArray(*object\srcMem, x, y, *object\width) = label
numNeighbors = 0
For i = 0 To 7
If getColorFromArray(*object\srcMem, x + indexedFilterMask(i), y, *object\width) = label
neighbors(i) = #True
numNeighbors + 1
Else
neighbors(i) = #False
EndIf
Next i
If numNeighbors < 2 Or numNeighbors > 6
Continue
EndIf
numTransitions = 0
For i = 0 To 7
If neighbors(i) = #False And neighbors((i + 1) % 8) = #True
numTransitions + 1
EndIf
Next i
If numTransitions <> 1
Continue
EndIf
If neighbors(0) And neighbors(2) And neighbors(4)
Continue
EndIf
If neighbors(2) And neighbors(4) And neighbors(6)
Continue
EndIf
setColorFromArray(*destMem, x, y, *object\width, $FFFFFF - label)
modified = #True
EndIf
Next x
Next y
CopyMemory(*destMem, *object\srcMem, *object\pixels * SizeOf(ImageFilter_RGBA))
For y = 1 To *object\height - 2
For x = 1 To *object\width - 2
If getColorFromArray(*object\srcMem, x, y, *object\width) = label
numNeighbors = 0
For i = 0 To 7
If getColorFromArray(*object\srcMem, x + indexedFilterMask(i), y, *object\width) = label
neighbors(i) = #True
numNeighbors + 1
Else
neighbors(i) = #False
EndIf
Next i
If numNeighbors < 2 Or numNeighbors > 6
Continue
EndIf
numTransitions = 0
For i = 0 To 7
If neighbors(i) = #False And neighbors((i + 1) % 8) = #True
numTransitions + 1
EndIf
Next i
If numTransitions <> 1
Continue
EndIf
If neighbors(0) And neighbors(2) And neighbors(6)
Continue
EndIf
If neighbors(0) And neighbors(4) And neighbors(6)
Continue
EndIf
setColorFromArray(*destMem, x, y, *object\width, $FFFFFF - label)
modified = #True
EndIf
Next x
Next y
*tmpMem = *destMem
*destMem = *object\srcMem
*object\srcMem = *tmpMem
Next t
FreeMemory(*destMem)
ProcedureReturn modified
EndProcedure
Procedure.i ImageFilter_skeletonization(*this.IImageFilter, label.i)
If *this = #Null
ProcedureReturn #False
EndIf
While *this\thin(label, 1) : Wend
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_generic(*this.IImageFilter, filter$)
Protected *object.OImageFilter, *destMem.ImageFilter_RGBA
If *this = #Null Or filter$ = ""
ProcedureReturn #False
EndIf
*object = *this
*destMem = *this\memGeneric(*object\srcMem, filter$)
If *destMem
FreeMemory(*object\srcMem)
*object\srcMem = *destMem
Else
ProcedureReturn #False
EndIf
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_bswap(*this.IImageFilter)
Protected *object.OImageFilter, gray.i, *src.ImageFilter_RGBA
If *this = #Null
ProcedureReturn #False
EndIf
*object = *this
*src = *object\srcMem
For i = 0 To *object\pixels - 1
Swap *src\channel[0], *src\channel[3]
Swap *src\channel[1], *src\channel[2]
*src + SizeOf(ImageFilter_RGBA)
Next i
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_output(*this.IImageFilter)
Protected *object.OImageFilter
If *this = #Null
ProcedureReturn #False
EndIf
*object = *this
ProcedureReturn *this\setColorArray(*object\srcMem)
EndProcedure
Procedure ImageFilter_delete(*this.IImageFilter)
Protected *object.OImageFilter
If *this = #Null
ProcedureReturn
EndIf
*object = *this
FreeMemory(*object\srcMem)
FreeMemory(*object)
EndProcedure
Procedure.i ImageFilter_getColorArray(*this.IImageFilter)
Protected *object.OImageFilter, *mem.ImageFilter_RGBA, *addr.ImageFilter_RGBA, *src.BYTE, *lineStart.BYTE
If *this = #Null
ProcedureReturn #Null
EndIf
*object = *this
*mem = AllocateMemory(*object\pixels * SizeOf(ImageFilter_RGBA))
If *mem = 0
ProcedureReturn #Null
EndIf
If StartDrawing(ImageOutput(*object\image)) = 0
FreeMemory(*mem)
ProcedureReturn #Null
EndIf
Select DrawingBufferPixelFormat() & $FF
Case #PB_PixelFormat_24Bits_RGB
*src = DrawingBuffer()
If *src = 0
FreeMemory(*mem)
StopDrawing()
ProcedureReturn #Null
EndIf
*addr = *mem
If DrawingBufferPixelFormat() & #PB_PixelFormat_ReversedY = #PB_PixelFormat_ReversedY
*src + ((*object\height - 1) * DrawingBufferPitch())
For y = 0 To *object\height - 1
*lineStart = *src
For x = 0 To *object\width - 1
*addr\channel[0] = *src\b : *src + 1
*addr\channel[1] = *src\b : *src + 1
*addr\channel[2] = *src\b : *src + 1
*addr\channel[3] = $FF
*addr + SizeOf(ImageFilter_RGBA)
Next x
*src = *lineStart - DrawingBufferPitch()
Next y
Else
For y = 0 To *object\height - 1
*lineStart = *src
For x = 0 To *object\width - 1
*addr\channel[0] = *src\b : *src + 1
*addr\channel[1] = *src\b : *src + 1
*addr\channel[2] = *src\b : *src + 1
*addr\channel[3] = $FF
*addr + SizeOf(ImageFilter_RGBA)
Next x
*src = *lineStart + DrawingBufferPitch()
Next y
EndIf
Case #PB_PixelFormat_24Bits_BGR
*src = DrawingBuffer()
If *src = 0
FreeMemory(*mem)
StopDrawing()
ProcedureReturn #Null
EndIf
*addr = *mem
If DrawingBufferPixelFormat() & #PB_PixelFormat_ReversedY = #PB_PixelFormat_ReversedY
*src + ((*object\height - 1) * DrawingBufferPitch())
For y = 0 To *object\height - 1
*lineStart = *src
For x = 0 To *object\width - 1
*addr\channel[2] = *src\b : *src + 1
*addr\channel[1] = *src\b : *src + 1
*addr\channel[0] = *src\b : *src + 1
*addr\channel[3] = $FF
*addr + SizeOf(ImageFilter_RGBA)
Next x
*src = *lineStart - DrawingBufferPitch()
Next y
Else
For y = 0 To *object\height - 1
*lineStart = *src
For x = 0 To *object\width - 1
*addr\channel[2] = *src\b : *src + 1
*addr\channel[1] = *src\b : *src + 1
*addr\channel[0] = *src\b : *src + 1
*addr\channel[3] = 0
*addr + SizeOf(ImageFilter_RGBA)
Next x
*src = *lineStart + DrawingBufferPitch()
Next y
EndIf
Case #PB_PixelFormat_32Bits_RGB
*src = DrawingBuffer()
If *src = 0
FreeMemory(*mem)
StopDrawing()
ProcedureReturn #Null
EndIf
*addr = *mem
If DrawingBufferPixelFormat() & #PB_PixelFormat_ReversedY = #PB_PixelFormat_ReversedY
*src + ((*object\height - 1) * DrawingBufferPitch())
For y = 0 To *object\height - 1
*lineStart = *src
For x = 0 To *object\width - 1
*addr\channel[0] = *src\b : *src + 1
*addr\channel[1] = *src\b : *src + 1
*addr\channel[2] = *src\b : *src + 1
*addr\channel[3] = *src\b : *src + 1
*addr + SizeOf(ImageFilter_RGBA)
Next x
*src = *lineStart - DrawingBufferPitch()
Next y
Else
For y = 0 To *object\height - 1
*lineStart = *src
For x = 0 To *object\width - 1
*addr\channel[0] = *src\b : *src + 1
*addr\channel[1] = *src\b : *src + 1
*addr\channel[2] = *src\b : *src + 1
*addr\channel[3] = *src\b : *src + 1
*addr + SizeOf(ImageFilter_RGBA)
Next x
*src = *lineStart + DrawingBufferPitch()
Next y
EndIf
Case #PB_PixelFormat_32Bits_BGR
*src = DrawingBuffer()
If *src = 0
FreeMemory(*mem)
StopDrawing()
ProcedureReturn #Null
EndIf
*addr = *mem
If DrawingBufferPixelFormat() & #PB_PixelFormat_ReversedY = #PB_PixelFormat_ReversedY
*src + ((*object\height - 1) * DrawingBufferPitch())
For y = 0 To *object\height - 1
*lineStart = *src
For x = 0 To *object\width - 1
*addr\channel[2] = *src\b : *src + 1
*addr\channel[1] = *src\b : *src + 1
*addr\channel[0] = *src\b : *src + 1
*addr\channel[3] = *src\b : *src + 1
*addr + SizeOf(ImageFilter_RGBA)
Next x
*src = *lineStart - DrawingBufferPitch()
Next y
Else
For y = 0 To *object\height - 1
*lineStart = *src
For x = 0 To *object\width - 1
*addr\channel[2] = *src\b : *src + 1
*addr\channel[1] = *src\b : *src + 1
*addr\channel[0] = *src\b : *src + 1
*addr\channel[3] = *src\b : *src + 1
*addr + SizeOf(ImageFilter_RGBA)
Next x
*src = *lineStart + DrawingBufferPitch()
Next y
EndIf
Default
*addr = *mem
If OutputDepth() = 32
For y = 0 To *object\height - 1
For x = 0 To *object\width - 1
*addr\rgba = Point(x, y)
*addr + SizeOf(ImageFilter_RGBA)
Next x
Next y
Else
For y = 0 To *object\height - 1
For x = 0 To *object\width - 1
*addr\rgba = Point(x, y)
*addr\channel[3] = $FF
*addr + SizeOf(ImageFilter_RGBA)
Next x
Next y
EndIf
EndSelect
StopDrawing()
ProcedureReturn *mem
EndProcedure
Procedure.i ImageFilter_setColorArray(*this.IImageFilter, *mem.ImageFilter_RGBA)
Protected *object.OImageFilter, *addr.ImageFilter_RGBA, *dest.BYTE, *lineStart.BYTE
If *this = #Null Or *mem = #Null
ProcedureReturn #False
EndIf
*object = *this
If StartDrawing(ImageOutput(*object\image)) = 0
ProcedureReturn #False
EndIf
Select DrawingBufferPixelFormat() & $FF
Case #PB_PixelFormat_24Bits_RGB
*dest = DrawingBuffer()
If *dest = 0
StopDrawing()
ProcedureReturn #False
EndIf
*addr = *mem
If DrawingBufferPixelFormat() & #PB_PixelFormat_ReversedY = #PB_PixelFormat_ReversedY
*dest + ((*object\height - 1) * DrawingBufferPitch())
For y = 0 To *object\height - 1
*lineStart = *dest
For x = 0 To *object\width - 1
*dest\b = *addr\channel[0] : *dest + 1
*dest\b = *addr\channel[1] : *dest + 1
*dest\b = *addr\channel[2] : *dest + 1
*addr + SizeOf(ImageFilter_RGBA)
Next x
*dest = *lineStart - DrawingBufferPitch()
Next y
Else
For y = 0 To *object\height - 1
*lineStart = *dest
For x = 0 To *object\width - 1
*dest\b = *addr\channel[0] : *dest + 1
*dest\b = *addr\channel[1] : *dest + 1
*dest\b = *addr\channel[2] : *dest + 1
*addr + SizeOf(ImageFilter_RGBA)
Next x
*dest = *lineStart + DrawingBufferPitch()
Next y
EndIf
Case #PB_PixelFormat_24Bits_BGR
*dest = DrawingBuffer()
If *dest = 0
StopDrawing()
ProcedureReturn #False
EndIf
*addr = *mem
If DrawingBufferPixelFormat() & #PB_PixelFormat_ReversedY = #PB_PixelFormat_ReversedY
*dest + ((*object\height - 1) * DrawingBufferPitch())
For y = 0 To *object\height - 1
*lineStart = *dest
For x = 0 To *object\width - 1
*dest\b = *addr\channel[2] : *dest + 1
*dest\b = *addr\channel[1] : *dest + 1
*dest\b = *addr\channel[0] : *dest + 1
*addr + SizeOf(ImageFilter_RGBA)
Next x
*dest = *lineStart - DrawingBufferPitch()
Next y
Else
For y = 0 To *object\height - 1
*lineStart = *dest
For x = 0 To *object\width - 1
*dest\b = *addr\channel[2] & $FF : *dest + 1
*dest\b = *addr\channel[1] & $FF : *dest + 1
*dest\b = *addr\channel[0] & $FF : *dest + 1
*addr + SizeOf(ImageFilter_RGBA)
Next x
*dest = *lineStart + DrawingBufferPitch()
Next y
EndIf
Case #PB_PixelFormat_32Bits_RGB
*dest = DrawingBuffer()
If *dest = 0
StopDrawing()
ProcedureReturn #False
EndIf
*addr = *mem
If DrawingBufferPixelFormat() & #PB_PixelFormat_ReversedY = #PB_PixelFormat_ReversedY
*dest + ((*object\height - 1) * DrawingBufferPitch())
For y = 0 To *object\height - 1
*lineStart = *dest
For x = 0 To *object\width - 1
*dest\b = *addr\channel[0] : *dest + 1
*dest\b = *addr\channel[1] : *dest + 1
*dest\b = *addr\channel[2] : *dest + 1
*dest\b = *addr\channel[3] : *dest + 1
*addr + SizeOf(ImageFilter_RGBA)
Next x
*dest = *lineStart - DrawingBufferPitch()
Next y
Else
For y = 0 To *object\height - 1
*lineStart = *dest
For x = 0 To *object\width - 1
*dest\b = *addr\channel[0] & $FF : *dest + 1
*dest\b = *addr\channel[1] & $FF : *dest + 1
*dest\b = *addr\channel[2] & $FF : *dest + 1
*dest\b = *addr\channel[3] & $FF : *dest + 1
*addr + SizeOf(ImageFilter_RGBA)
Next x
*dest = *lineStart + DrawingBufferPitch()
Next y
EndIf
Case #PB_PixelFormat_32Bits_BGR
*dest = DrawingBuffer()
If *dest = 0
StopDrawing()
ProcedureReturn #False
EndIf
*addr = *mem
If DrawingBufferPixelFormat() & #PB_PixelFormat_ReversedY = #PB_PixelFormat_ReversedY
*dest + ((*object\height - 1) * DrawingBufferPitch())
For y = 0 To *object\height - 1
*lineStart = *dest
For x = 0 To *object\width - 1
*dest\b = *addr\channel[2] : *dest + 1
*dest\b = *addr\channel[1] : *dest + 1
*dest\b = *addr\channel[0] : *dest + 1
*dest\b = *addr\channel[3] : *dest + 1
*addr + SizeOf(ImageFilter_RGBA)
Next x
*dest = *lineStart - DrawingBufferPitch()
Next y
Else
For y = 0 To *object\height - 1
*lineStart = *dest
For x = 0 To *object\width - 1
*dest\b = *addr\channel[2] & $FF : *dest + 1
*dest\b = *addr\channel[1] & $FF : *dest + 1
*dest\b = *addr\channel[0] & $FF : *dest + 1
*dest\b = *addr\channel[3] & $FF : *dest + 1
*addr + SizeOf(ImageFilter_RGBA)
Next x
*dest = *lineStart + DrawingBufferPitch()
Next y
EndIf
Default
*addr = *mem
If OutputDepth() = 32
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, *object\width, *object\height, $00000000)
DrawingMode(#PB_2DDrawing_AlphaBlend)
EndIf
For y = 0 To *object\height - 1
For x = 0 To *object\width - 1
Plot(x, y, *addr\rgba)
*addr + SizeOf(ImageFilter_RGBA)
Next x
Next y
EndSelect
StopDrawing()
ProcedureReturn #True
EndProcedure
Procedure.i ImageFilter_memBinomial(*this.IImageFilter, *mem.ImageFilter_RGBA, size.i)
Protected *object.OImageFilter, src1.ImageFilter_RGBA, src2.ImageFilter_RGBA, *srcMem.ImageFilter_RGBA, *destMem.ImageFilter_RGBA
Protected int.i, offset.i
If *this = #Null Or *mem = #Null
ProcedureReturn #Null
EndIf
*object = *this
*srcMem = AllocateMemory(*object\pixels * SizeOf(ImageFilter_RGBA))
If *srcMem = #Null
ProcedureReturn #Null
EndIf
If size < 2
CopyMemory(*mem, *srcMem, *object\pixels * SizeOf(ImageFilter_RGBA))
ProcedureReturn *srcMem
EndIf
*destMem = AllocateMemory(*object\pixels * SizeOf(ImageFilter_RGBA))
If *destMem = #Null
ProcedureReturn #Null
EndIf
CopyMemory(*mem, *srcMem, *object\pixels * SizeOf(ImageFilter_RGBA))
offset = 1
For p = 2 To size
For y = 0 To *object\height - 1
For x = offset To *object\width - 2 + offset
src1\rgba = getColorFromArray(*srcMem, x - offset, y, *object\width)
src2\rgba = getColorFromArray(*srcMem, x + 1 - offset, y, *object\width)
For channel = 0 To #IF_UsedChannels - 1
int = (src1\channel[channel] & $FF) + (src2\channel[channel] & $FF)
src1\channel[channel] = Int(int / 2)
Next channel
setColorFromArray(*destMem, x, y, *object\width, src1\rgba)
Next x
If offset = 0
src1\rgba = getColorFromArray(*srcMem, *object\width - 1, y, *object\width)
setColorFromArray(*destMem, *object\width - 1, y, *object\width, src1\rgba)
Else
src1\rgba = getColorFromArray(*srcMem, 0, y, *object\width)
setColorFromArray(*destMem, 0, y, *object\width, src1\rgba)
EndIf
Next y
For x = 0 To *object\width - 1
For y = offset To *object\height - 2 + offset
src1\rgba = getColorFromArray(*destMem, x, y - offset, *object\width)
src2\rgba = getColorFromArray(*destMem, x, y + 1 - offset, *object\width)
For channel = 0 To #IF_UsedChannels - 1
int = (src1\channel[channel] & $FF) + (src2\channel[channel] & $FF)
src1\channel[channel] = Int(int / 2)
Next channel
setColorFromArray(*srcMem, x, y, *object\width, src1\rgba)
Next y
If offset = 0
src1\rgba = getColorFromArray(*destMem, x, *object\height - 1, *object\width)
setColorFromArray(*srcMem, x, *object\height - 1, *object\width, src1\rgba)
Else
src1\rgba = getColorFromArray(*destMem, x, 0, *object\width)
setColorFromArray(*srcMem, x, 0, *object\width, src1\rgba)
EndIf
Next x
offset = 1 - offset
Next
FreeMemory(*destMem)
ProcedureReturn *srcMem
EndProcedure
Procedure.i ImageFilter_memGeneric(*this.IImageFilter, *srcMem.ImageFilter_RGBA,filter$)
Protected *object.OImageFilter, *destMem.ImageFilter_RGBA
Protected src.ImageFilter_RGBA, dest.ImageFilter_RGBA, curColor.i
Protected filterWidth.i, filterHeight.i, filterOffsetX.i, filterOffsetY.i
Protected filterMatrix$, divide.f, offset.f
Protected newValue.f
If *this = #Null Or *srcMem = #Null
ProcedureReturn #Null
EndIf
*object = *this
*destMem = AllocateMemory(*object\pixels * SizeOf(ImageFilter_RGBA))
If *destMem = #Null
ProcedureReturn #Null
EndIf
CopyMemory(*srcMem, *destMem, *object\pixels * SizeOf(ImageFilter_RGBA))
filterMatrix$ = Trim(StringField(filter$, 1, ";"))
divide = ValF(Trim(StringField(filter$, 2, ";")))
offset = ValF(Trim(StringField(filter$, 3, ";")))
filterWidth = CountString(StringField(filterMatrix$, 1, "|"), ",") + 1
filterHeight = CountString(filterMatrix$, "|") + 1
Protected Dim filter.f(filterWidth - 1, filterHeight - 1)
For x = 0 To filterWidth - 1
For y = 0 To filterHeight - 1
filter(x, y) = ValF(Trim(StringField(StringField(filterMatrix$, y + 1, "|"), x + 1, ",")))
Next
Next
filterOffsetX = filterWidth >> 1
filterOffsetY = filterHeight >> 1
For x = filterOffsetX To *object\width - filterOffsetX - 1
For y = filterOffsetY To *object\height - filterOffsetY - 1
For channel = 0 To #IF_UsedChannels - 1
newValue = 0
For xi = x - filterOffsetX To x + filterOffsetX
For yi = y - filterOffsetY To y + filterOffsetY
src\rgba = getColorFromArray(*srcMem, xi, yi, *object\width)
curColor = src\channel[channel] & $FF
newValue = newValue + (curColor * filter(xi - x + filterOffsetX, yi - y + filterOffsetY))
Next yi
Next xi
newValue = (newValue / divide) + offset
limit(newValue, 0, 255)
dest\channel[channel] = newValue
Next channel
setColorFromArray(*destMem, x, y, *object\width, dest\rgba)
Next y
Next x
ProcedureReturn *destMem
EndProcedure
; ;########################################
; UseJPEGImageDecoder()
;
; img = LoadImage(#PB_Any, "D:\Downloads\Backgrounds\getme.jpg")
;
; filter1.IImageFilter = newImageFilter(img)
; filter2.IImageFilter = newImageFilter(img)
; filter3.IImageFilter = newImageFilter(img)
;
; filter1\median(1)
; filter1\generic("1,2,1|0,0,0|-1,-2,-1;8;128")
;
; filter2\median(1)
; filter2\generic("1,0,-1|2,0,-2|1,0,-1;8;128")
; filter2\euclidianNorm(filter1, 0)
; filter2\invert()
; filter2\grayscale()
;
; filter3\median(1)
; filter3\weight(filter2, 1, -128)
; filter3\median(1)
; filter3\output()
;
; filter1\delete()
; filter2\delete()
; filter3\delete()
;
; OpenWindow(0, 0, 0, ImageWidth(img), ImageHeight(img), "CImageFilter", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
; ImageGadget(0, 0, 0, ImageWidth(img), ImageHeight(img), ImageID(img))
; Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow