Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'Coded by UEZ build 2024-04-17 beta
- 'Good source: http://www.codeproject.com/Articles/781213/Fundamentals-of-Image-Processing-behind-the-scenes by Jakub Szymanowski
- #ifdef __FB_64BIT__
- #cmdline "-m _GDIPlus_BitmapApplyFilter_x64 -dll -export -gen gcc -Wc -Ofast -Wc -march=native -Wc -funroll-loops -Wc -mfpmath=sse"
- #else
- #cmdline "-m _GDIPlus_BitmapApplyFilter -dll -export -gen gcc -Wc -Ofast -Wc -march=native -Wc -funroll-loops -Wc -mfpmath=sse"
- #endif
- '#Include Once "crt\stdlib.bi"
- '#Include Once "crt\math.bi"
- '#Include Once "win\gdiplus.bi"
- '#Include Once "win\winuser.bi"
- '#Include Once "windows.bi"
- #include once "fbgfx.bi"
- #include once "delaunay.bi"
- #include once "poisson-sampler.bi"
- #ifdef __FB_64BIT__
- #inclib "gdiplus"
- #include once "win/gdiplus-c.bi"
- #else
- #include once "win/gdiplus.bi"
- Using Gdiplus
- #endif
- #define CRLF (Chr(13, 10))
- #define _Red(c) ((c And &h00FF0000) Shr 16)
- #define _Green(c) ((c And &h0000FF00) Shr 8)
- #define _Blue(c) ((c And &h000000FF))
- #define Map(Val, source_start, source_stop, dest_start, dest_stop) ((Val - source_start) * (dest_stop - dest_start) / (source_stop - source_start) + dest_start)
- Public Const sVersion = "v0.9.8 build 2024-04-17 beta", fPi = Acos(-1), fPiSqr = Sqr(2 * fPi), f2Pi = 2 * fPi, fRad = fPi / 180
- Type tagPalette
- Flags As ULong
- Count As ULong
- ARGB(256) As ULong
- End Type
- Extern "Windows-MS"
- Enum Filters
- EMBOSS1 = 1, EMBOSS2, EMBOSS3, EMBOSS4, SHARPEN1, BOX_BLUR, GAUSSIAN_BLUR, TRIANGLE_BLUR, UNSHARP, UNSHARP5x5, _
- EDGE_DETECTION1, EDGE_DETECTION2, EDGE_DETECTION3, EDGE_DETECTION4, EDGE_DETECTION5, EDGE_DETECTION6, _
- ANOTHER_BLUR, MOTION_BLUR, SHARPEN2, SOBEL, LAPLACE3x3_1, LAPLACE3x3_2, LAPLACE5x5, PREWITT, KIRSCH, _
- OUTLINE3X3, GAUSSIAN5X5_1, GAUSSIAN5X5_2, LAPLACIANOFGAUSSIAN, SOVELVSPREWITT, GAUSSIAN3X3
- End Enum
- 'Jarvis, Judice, and Ninke
- Dim Shared As Single matrixJJN(0 To ..., 0 To ...) = {{0, 0, 0, 7/48, 5/48}, _
- {3/48, 5/48, 7/48, 5/48, 3/48}, _
- {1/48, 3/48, 5/48, 3/48, 1/48}}
- 'Atkinson
- Dim Shared As Single matrixAtkinson(0 To ..., 0 To ...) = {{0, 0, 1/8, 1/8}, _
- {1/8, 1/8, 1/8, 0}, _
- {0, 1/8, 0, 0}}
- 'Burkes
- Dim Shared As Single matrixBurkes(0 To ..., 0 To ...) = {{0, 0, 0, 8/32, 4/32}, _
- {2/32, 4/32, 8/32, 4/32, 2/32}}
- 'Two-Row Sierra
- Dim Shared As Single matrixSierra2(0 To ..., 0 To ...) = {{0, 0, 0, 4/16, 3/16}, _
- {1/16, 2/16, 3/16, 2/16, 1/16}}
- 'Three-Row Sierra
- Dim Shared As Single matrixSierra3(0 To ..., 0 To ...) = {{0, 0, 0, 5/32, 3/32}, _
- {2/32, 4/32, 5/32, 4/32, 2/32}, _
- {0, 2/32, 3/32, 2/32, 0}}
- 'Floyd-Steinberg
- Dim Shared As Single matrixFS(0 To ..., 0 To ...) = {{0, 0, 7/16}, _
- {3/16, 5/16, 1/16}}
- 'Stucki
- Dim Shared As Single matrixStucki(0 To ..., 0 To ...) = {{0, 0, 0, 8/42, 4/42}, _
- {2/42, 4/42, 8/42, 4/42, 2/42}, _
- {1 / 42, 2 / 42, 4 / 42, 2 / 42, 1 / 42}}
- Dim Shared As Single matrixErrorDiffusion(0 To ..., 0 To ...) = _
- {{0, 0, 0, 2 / 14, 1 / 14}, _
- {0, 2 / 14, 2 / 14, 2 / 14, 0 }, _
- {1 / 14, 0, 1 / 14, 0, 1 / 14}}
- 'Bayer-method ordered dither
- Dim Shared As Single matrixBayer(0 To ..., 0 To ...) = _
- {{ 0, 32, 8, 40, 2, 34, 10, 42}, _
- {48, 16, 56, 24, 50, 18, 58, 26}, _
- {12, 44, 4, 36, 14, 46, 6, 38}, _
- {60, 28, 52, 20, 62, 30, 54, 22}, _
- { 3, 35, 11, 43, 1, 33, 9, 41}, _
- {51, 19, 59, 27, 49, 17, 57, 25}, _
- {15, 47, 7, 39, 13, 45, 5, 37}, _
- {63, 31, 55, 23, 61, 29, 53, 21}}
- Declare Function QCompare cdecl (ByVal e1 As Any Ptr, ByVal e2 As Any Ptr) As Integer
- Declare Function __DeltaE(iR1 As Long, iG1 As Long, iB1 As Long, iR2 As Long, iG2 As Long, iB2 As Long) As Single
- Declare Function _GDIPlus_ImageCountColors(himage As Any Ptr) As ULong
- Declare Function _GDIPlus_BitmapGetAverageColorValue(hImage As Any Ptr, bNegRGB As BOOL) As ULong
- Declare Function _GDIPlus_BitmapCreateBW(hImage As Any Ptr, iThreshold As UShort, bGDI As BOOL = False) As Any Ptr
- Declare Function _GDIPlus_BitmapCreateGreyscale(hImage As Any Ptr, bGDI As BOOL = False) As Any Ptr
- Declare Function _GDIPlus_BitmapCreateNegative(hImage As Any Ptr, bGDI As BOOL = False) As Any Ptr
- Declare Function _GDIPlus_BitmapCreateInverseGreyscale(hImage As Any Ptr, iThreshold As ULong) As Any Ptr
- Declare Function _GDIPlus_BitmapCreateFakeGreyscale(hImage As Any Ptr, bGDI As BOOL = False) As Any Ptr
- Declare Function _GDIPlus_BitmapCreateInverseBW(hImage As Any Ptr, iThreshold As UByte) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Blur(ByVal hImage As Any Ptr, iRadius As UByte) As Any Ptr
- Declare Function _Min3(fR As Single, fG As Single, fB As Single) As Single
- Declare Function _Max3(fR As Single, fG As Single, fB As Single) As Single
- Declare Function FindNearestColor(iColor As ULong, ByRef tColorPalette As tagPalette Ptr, iColors As ULong) As ULong
- Declare Function PlusTruncate(a As UByte, b As Single) As UByte
- Declare Sub CopyArray(a() As Single, b() As Single)
- Declare Sub drawTriangles(hImageSource As Any Ptr, hImageDestination As Any Ptr, v() As DTVertex, t() As DTTriangle, tcount As Long, bShowEdges As BOOL = False, iAlpha As UByte = &h60, bWireframe As BOOL = False)
- Declare Function _GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour(ByVal hImage As Any Ptr, fRadius As Single, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Jitter(ByVal hImage As Any Ptr, iAmount As ULong, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Median(ByVal hImage As Any Ptr, fRadius As Single, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Kuwahara(ByVal hImage As Any Ptr, iSize As ULong, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Edges(ByVal hImage As Any Ptr, bMode As UByte, bInverse As BOOL, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Pointillism(ByVal hImage As Any Ptr, iRounds As ULong, iSize As ULong, iA As UByte, bBorder As BOOL, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Linellism(ByVal hImage As Any Ptr, iRounds As ULong, iSize As ULong, iA As UByte, iMode As UByte, bBorder As BOOL, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Convolution(ByVal hImage As Any Ptr, fFactor As Single, fBias As Single, iMode As UByte, pMStruct As Any Ptr, iMatrix As UShort, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Raster(ByVal hImage As Any Ptr, iSizeW As ULong, iSizeH As ULong, fDensity As Single, fBrightness As Single, fBias As Single, iMode As Byte, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Rasterize(ByVal hImage As Any Ptr, iSpaceX As ULong, iSpaceY As ULong, iDelCol As ULong, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Pixelate(ByVal hImage As Any Ptr, iPixelate As UByte, bGrid As BOOL, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Dilatation(ByVal hImage As Any Ptr, Size As UByte, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Erosion(ByVal hImage As Any Ptr, Size As UByte, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_OilPainting(ByVal hImage As Any Ptr, iRadius As UByte, fIntensityLevels As Single, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_ColorAccent(ByVal hImage As Any Ptr, iHue As UShort, fRange As Single, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_PenSketch(ByVal hImage As Any Ptr, iThreshold As Single, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_PenSketch2(ByVal hImage As Any Ptr, iThreshold As UByte, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Cartoon1(ByVal hImage As Any Ptr, iRadius As UByte, fIntensityLevels As Single, iThreshold As UByte, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_TiltShift(ByVal hImage As Any Ptr, fPosY_Start As Single, iIntensity As UByte, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_RadialBlur(ByVal hImage As Any Ptr, fPosX As Single, fPosY As Single, fRadius As Single, iIntensity As UByte, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_TimeWarp(ByVal hImage As Any Ptr, fFactor As Single, fMidX As Single, fMidY As Single, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_FishEye(ByVal hImage As Any Ptr, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Wave(ByVal hImage As Any Ptr, fAmplitudeX As Single, fAmplitudeY As Single, fFrequencyX As Single, fFrequencyY As Single, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Swirl(ByVal hImage As Any Ptr, fDegree As Single, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_XRay(ByVal hImage As Any Ptr, iBias As Byte, bInvert As BOOL, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Median2(ByVal hImage As Any Ptr, fRadius As Single, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_BWJJNDithering(ByVal hImage As Any Ptr, fErrorMultiplier As Single, iThreshold As UByte, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_BWBayerDithering(ByVal hImage As Any Ptr, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Indexed(ByVal hImage As Any Ptr, iColors As ULong, bDither As BOOL, iDitherType As UByte, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Mosaic(ByVal hImage As Any Ptr, iSites As ULong, bOrdered As BOOL, bBorder As BOOL, iCalcMode As UByte, iBorderColor As ULong, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_WaterDropGlassPane(ByVal hImage As Any Ptr, iPosX As UShort, iPosY As UShort, iAmount As UShort, iSizeMin As UByte, iSizeMax As UShort, iBlur As UByte, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Delaunay(ByVal hImage As Any Ptr, iBlur As UByte, fSobel As Single, iBW As UByte, iSpaceX As ULong, iSpaceY As ULong, iBorderSpaceX As UByte, iBorderSpaceY As UByte, _
- bRndPoints As BOOL, iRndPoints As ULong, bShowEdges As BOOL, iAlpha As UByte, bWireframe As BOOL, bGDI As BOOL) As Any Ptr
- Declare Function _GDIPlus_BitmapApplyFilter_Spiral(ByVal hImage As Any Ptr, iMode As UByte, iBgColor As ULong, bGreyScale As BOOL, bGDI As BOOL) As Any Ptr
- Sub Ver() Export
- MessageBoxEx(NULL, "_GDIPlus_BitmapApplyFilter.dll" & CRLF & CRLF & _
- sVersion & CRLF & CRLF & CRLF & _
- "Coded by UEZ" & CRLF & CRLF & CRLF & _
- "Credits to:" & CRLF & _
- "* Jakub Szymanowski" & CRLF & _
- "* rdc" & CRLF & _
- "* Dewald Esterhuizen" & CRLF & _
- "* Santhosh G_ " & CRLF & _
- "* Christian Graus" & CRLF & _
- "* paul doe" & CRLF & _
- "* www.gutgames.com" & CRLF & _
- "* D.J. Peters", _
- "DLL Information", MB_ICONINFORMATION Or MB_OK Or MB_APPLMODAL Or MB_TOPMOST, 1033)
- End Sub
- 'Perlin Noise by Joshy aka D.J. Peters
- Type REAL As Single
- #define rAbs(x_) IIf( (x_) < 0, -(x_), (x_) )
- Const As REAL rPI = Acos(-1)
- Const As REAL rDeg2Rad = rPI / 180
- Type PERLINNOISE '...'
- Declare Constructor
- Declare Sub NoiseSeed(ByVal seed As Double)
- Declare Sub NoiseDetail(ByVal lod As Integer)
- Declare Sub NoiseDetail(ByVal lod As Integer, ByVal falloff As REAL)
- Declare Function Noise1D(ByVal x As REAL) As REAL
- Declare Function Noise2D(ByVal x As REAL,ByVal y As REAL) As REAL
- Declare Function Noise3D(ByVal x As REAL,ByVal y As REAL,ByVal z As REAL) As REAL
- Private:
- Const As REAL SINCOS_PRECISION = 0.5
- Const As Integer SINCOS_LENGTH = (360 / SINCOS_PRECISION)
- Const As Integer PERLIN_YWRAPB = 4
- Const As Integer PERLIN_YWRAP = 1 Shl PERLIN_YWRAPB
- Const As Integer PERLIN_ZWRAPB = 8
- Const As Integer PERLIN_ZWRAP = 1 Shl PERLIN_ZWRAPB
- Const As Integer PERLIN_SIZE = 4095
- Const As Integer PERLIN_TWOPI = SINCOS_LENGTH
- Const As Integer PERLIN_PI = PERLIN_TWOPI Shr 1
- As Integer perlin_octaves = 4 ' default To medium smooth
- As REAL perlin_amp_falloff = 0.5 ' 50% reduction/octave
- As REAL perlin_cosTable(SINCOS_LENGTH-1)
- As REAL perlin(PERLIN_SIZE)
- Declare Sub reInit
- Declare Function noise_fsc(ByVal i As REAL) As REAL
- End Type
- Constructor PERLINNOISE '...'
- For i As Integer = 0 To SINCOS_LENGTH - 1
- perlin_cosTable(i) = Cos(i * rDeg2Rad * SINCOS_PRECISION)
- Next
- reInit
- End Constructor
- Sub PERLINNOISE.reInit '...'
- Randomize
- For i As Integer = 0 To PERLIN_SIZE
- perlin(i) = Rnd()
- Next
- End Sub
- Function PERLINNOISE.noise_fsc(ByVal i As REAL) As REAL '...'
- Dim As Integer index = Int(i * PERLIN_PI)
- Return 0.5 * (1.0 - perlin_cosTable(index Mod SINCOS_LENGTH))
- End Function
- Sub PERLINNOISE.noiseSeed(ByVal seed As Double) '...'
- 'Randomize(0) ' !!!
- Randomize(seed) : reInit
- End Sub
- Sub PERLINNOISE.noiseDetail(ByVal lod As Integer) '...'
- If (lod > 0) Then perlin_octaves = lod
- End Sub
- Sub PERLINNOISE.noiseDetail(ByVal lod As Integer, ByVal falloff As REAL) '...'
- If (lod > 0) Then perlin_octaves = lod
- If (falloff > 0) Then perlin_amp_falloff = falloff
- End Sub
- Function PERLINNOISE.Noise1D(ByVal x As REAL) As REAL '...'
- Return noise3D(x, 0, 0)
- End Function
- Function PERLINNOISE.Noise2D(ByVal x As REAL, ByVal y As REAL) As REAL '...'
- Return noise3D(x, y, 0)
- End Function
- Function PERLINNOISE.Noise3D(ByVal x As REAL,ByVal y As REAL,ByVal z As REAL) As REAL '...'
- x = rAbs(x) : y = rAbs(y) : z = rAbs(z)
- Dim As Integer xi = Int(x), yi = Int(y), zi = Int(z)
- Dim As REAL xf = x - xi, yf = y - yi, zf = z - zi
- Dim As REAL r, ampl = 0.5
- For i As Integer = 0 To perlin_octaves - 1
- Dim As Integer of= xi + (yi Shl PERLIN_YWRAPB) + (zi Shl PERLIN_ZWRAPB)
- Dim As REAL rxf = noise_fsc(xf)
- Dim As REAL ryf = noise_fsc(yf)
- Dim As REAL n1 = perlin(of And PERLIN_SIZE)
- n1 += rxf * (perlin((of + 1) And PERLIN_SIZE) - n1)
- Dim As REAL n2 = perlin((of + PERLIN_YWRAP) And PERLIN_SIZE)
- n2 += rxf * (perlin((of + PERLIN_YWRAP + 1) And PERLIN_SIZE) - n2)
- n1 += ryf * (n2 - n1)
- of += PERLIN_ZWRAP
- n2 = perlin(of And PERLIN_SIZE)
- n2 += rxf * (perlin((of + 1) And PERLIN_SIZE) - n2)
- Dim As REAL n3 = perlin((of + PERLIN_YWRAP) And PERLIN_SIZE)
- n3 += rxf * (perlin((of + PERLIN_YWRAP + 1) And PERLIN_SIZE) - n3)
- n2 += ryf * (n3 - n2)
- n1 += noise_fsc(zf) * (n2 - n1)
- r += n1 * ampl
- ampl *= perlin_amp_falloff
- xi Shl = 1: xf *= 2
- yi Shl = 1: yf *= 2
- zi Shl = 1: zf *= 2
- If (xf >= 1) Then xi += 1 : xf -= 1
- If (yf >= 1) Then yi += 1 : yf -= 1
- If (zf >= 1) Then zi += 1 : zf -= 1
- Next
- Return r
- End Function
- 'End Perlin Noise
- 'The qsort function expects three numbers
- 'from the compare function:
- '-1: if e1 is less than e2
- '0: if e1 is equal to e2
- '1: if e1 is greater than e2
- Private Function QCompare cdecl (ByVal e1 As Any Ptr, ByVal e2 As Any Ptr) As Integer 'code by rdc '...'
- Dim As Integer el1, el2
- Static cnt As Integer
- 'Get the call count and items passed
- cnt += 1
- 'Get the values, must cast to integer ptr
- el1 = *(CPtr(Integer Ptr, e1))
- el2 = *(CPtr(Integer Ptr, e2))
- 'Print "Qsort called";cnt;" time(s) with";el1;" and";el2;"."
- 'Compare the Values
- If el1 < el2 Then
- Return -1
- ElseIf el1 > el2 Then
- Return 1
- Else
- Return 0
- End If
- End Function
- Private Function __DeltaE(iR1 As Long, iG1 As Long, iB1 As Long, iR2 As Long, iG2 As Long, iB2 As Long) As Single '...'
- Return Sqr((iR1 - iR2) * (iR1 - iR2) + (iG1 - iG2) * (iG1 - iG2) + (iB1 - iB2) * (iB1 - iB2))
- End Function
- Private Function _Min3(fRed As Single, fGreen As Single, fBlue As Single) As Single '...'
- Dim As Single fSmallest = fRed
- If fSmallest > fGreen Then fSmallest = fGreen
- If fSmallest > fBlue Then fSmallest = fBlue
- Return fSmallest
- End Function
- Private Function _Max3(fRed As Single, fGreen As Single, fBlue As Single) As Single '...'
- Dim As Single fBiggest = fRed
- If fBiggest < fGreen Then fBiggest = fGreen
- If fBiggest < fBlue Then fBiggest = fBlue
- Return fBiggest
- End Function
- 'https://en.wikibooks.org/wiki/Algorithm_Implementation/Sorting/Quicksort
- Private Sub Quicksort(Array() As ULong, iStart As ULong, iEnd As ULong) '...'
- Dim As UInteger i = iStart, j = iEnd, iPivot = Array((i + j) Shr 1)
- While i <= j
- While Array(i) > iPivot
- i += 1
- Wend
- While Array(j) < iPivot
- j -= 1
- Wend
- If i <= j Then
- Swap Array(i), Array(j)
- i += 1
- j -= 1
- End If
- Wend
- If j > iStart Then Quicksort(Array(), iStart, j)
- If i < iEnd Then Quicksort(Array(), i, iEnd)
- End Sub
- Private Function _GDIPlus_ImageGetPixelFormat(hImage As Any Ptr) As ULong '...'
- Dim As Long iFormat
- GdipGetImagePixelFormat(hImage, @iFormat)
- Return iFormat
- End Function
- Private Function _GDIPlus_BitmapGetAverageColorValue(hImage As Any Ptr, bNegRGB As BOOL) As ULong '...'
- Dim As Single iW, iH
- Dim As BitmapData tBitmapData
- Dim As ULong iX, iY, iRowOffset, c, iCount, iA, iR, iG, iB
- Dim As ULong sumA = 0, sumR = 0, sumG = 0, sumB = 0
- GdipGetImageDimension(hImage, @iW, @iH)
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- iCount = iW * iH
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- c = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- sumA += (c Shr 24) And &hFF
- sumR += (c Shr 16) And &hFF
- sumG += (c Shr 8) And &hFF
- sumB += c And &hFF
- Next
- Next
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bNegRGB Then
- iA = CLng(sumA / iCount) Shl 24
- iR = (&hFF - CLng(sumR / iCount)) Shl 16
- iG = (&hFF - CLng(sumG / iCount)) Shl 8
- iB = (&hFF - CLng(sumB / iCount))
- Else
- iA = CLng(sumA / iCount) Shl 24
- iR = CLng(sumR / iCount) Shl 16
- iG = CLng(sumG / iCount) Shl 8
- iB = CLng(sumB / iCount)
- EndIf
- Return iA + iR + iG + iB
- End Function
- Private Function _GDIPlus_ImageCountColors32(himage As Any Ptr) As ULong 'slower variant but full 32-bit support '...'
- Dim As Single iW, iH, iPixel, iRowOffset
- GdipGetImageDimension(himage, @iW, @iH)
- Dim As BitmapData tBitmapData
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- Dim As ULong aColors(0 To iW * iH - 1), c = 0, iX, iY
- _GDIPlus_ImageGetPixelFormat(himage)
- GdipBitmapLockBits(himage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- aColors(c) = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- c += 1
- Next
- Next
- GdipBitmapUnlockBits(himage, @tBitmapData)
- Quicksort(aColors(), 0, c - 1)
- c = 0
- For iY = 0 To UBound(aColors) - 2
- If aColors(iY) > aColors(iY + 1) Then c += 1
- Next
- Return c
- End Function
- Private Function _GDIPlus_ImageCountColors24ASM(himage As Any Ptr) As ULong '...'
- Dim As Single iW, iH, iPixel
- GdipGetImageDimension(himage, @iW, @iH)
- Dim As BitmapData tBitmapData
- Dim As RECT tRect = Type(0, 0, iW, iH)
- Dim As UInteger c = 0, iPixels = iW * iH - 1
- Dim As UByte aColors()
- ReDim aColors(0 To 256^3)
- GdipBitmapLockBits(himage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- Dim As Integer Ptr pBmp = Cast(Any Ptr, tBitmapData.Scan0)
- Dim As Byte Ptr pColors = @aColors(0)
- #ifndef __FB_64BIT__ '...'
- #define REG_AX eax
- #define REG_BX ebx
- #define REG_CX ecx
- #define REG_DX edx
- #define REG_DI edi
- #define REG_SI esi
- #define REG_SP esp
- #define REG_BP ebp
- #else
- #define REG_AX rax
- #define REG_BX rbx
- #define REG_CX rcx
- #define REG_DX rdx
- #define REG_DI rdi
- #define REG_SI rsi
- #define REG_SP rsp
- #define REG_BP rbp
- #endif
- Asm '...'
- mov REG_SI, [pBmp]
- mov REG_CX, [iPixels]
- mov REG_DI, [pColors]
- xor REG_AX, REG_AX
- _Pixel_Count:
- mov REG_BX, [REG_SI]
- and REG_BX, &hFFFFFF
- cmp byte ptr [REG_DI + REG_BX], 1
- je _Next
- add REG_AX, 1
- mov byte ptr [REG_DI + REG_BX], 1
- _Next:
- add REG_SI, 4
- sub REG_CX, 1
- jnz _Pixel_Count
- mov [c], REG_AX
- End Asm
- GdipBitmapUnlockBits(himage, @tBitmapData)
- Return c
- End Function
- Function _GDIPlus_ImageCountColors(himage As Any Ptr) As ULong Export '...'
- If (_GDIPlus_ImageGetPixelFormat(himage) And PixelFormatAlpha) Then Return _GDIPlus_ImageCountColors32(himage) 'check if image has alpha channel
- Return _GDIPlus_ImageCountColors24ASM(himage)
- End Function
- Function _GDIPlus_BitmapCreateBW(himage As Any Ptr, iThreshold As UShort, bGDI As BOOL = False) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_BW, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_BW
- Dim As Long iX, iY, iRowOffset, iColor, iR, iG, iB
- iThreshold = IIf(iThreshold < 0, 0, IIf(iThreshold > 255, 255, iThreshold))
- GdipGetImageDimension(himage, @iW, @iH)
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_BW)
- GdipBitmapLockBits(hBitmap_BW, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_BW)
- GdipBitmapLockBits(himage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- iColor = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- iR = (iColor Shr 16) And &hFF
- iG = (iColor Shr 8) And &hFF
- iB = iColor And &hFF
- If CLng((iR + iG + iB) / 3) >= iThreshold Then
- Cast(ULong Ptr, tBitmapData_BW.Scan0)[iRowOffset + iX] = &hFFFFFFFF
- Else
- Cast(ULong Ptr, tBitmapData_BW.Scan0)[iRowOffset + iX] = &hFF000000
- End If
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_BW, @tBitmapData_BW)
- GdipBitmapUnlockBits(himage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_BW, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_BW)
- Return hGDIBitmap
- EndIf
- Return hBitmap_BW
- End Function
- Function _GDIPlus_BitmapCreateGreyscale(hImage As Any Ptr, bGDI As BOOL = False) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Greyscale, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Greyscale
- Dim As Long iX, iY, iRowOffset, iColor, c, iR, iG, iB
- GdipGetImageDimension(hImage, @iW, @iH)
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Greyscale)
- GdipBitmapLockBits(hBitmap_Greyscale, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Greyscale)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- iColor = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- iR = (iColor Shr 16) And &hFF
- iG = (iColor Shr 8) And &hFF
- iB = iColor And &hFF
- c = CLng((iR * 213 + iG * 715 + iB * 72) / 1000)
- Cast(ULong Ptr, tBitmapData_Greyscale.Scan0)[iRowOffset + iX] = &hFF000000 + (c Shl 16) + (c Shl 8) + c
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Greyscale, @tBitmapData_Greyscale)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Greyscale, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Greyscale)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Greyscale
- End Function
- Function _GDIPlus_BitmapCreateNegative(hImage As Any Ptr, bGDI As BOOL = False) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Negative, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Negative
- Dim As Long iX, iY, iRowOffset
- GdipGetImageDimension(hImage, @iW, @iH)
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Negative)
- GdipBitmapLockBits(hBitmap_Negative, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Negative)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- Cast(ULong Ptr, tBitmapData_Negative.Scan0)[iRowOffset + iX] = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX] Xor &h00FFFFFF
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Negative, @tBitmapData_Negative)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Negative, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Negative)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Negative
- End Function
- Function _GDIPlus_BitmapCreateFakeGreyscale(hImage As Any Ptr, bGDI As BOOL = False) As Any Ptr Export
- Dim As Single iW, iH
- Dim As Double fGreys, fLuma
- Dim As Any Ptr hBitmap_Greyscale, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Greyscale
- Dim As Long iX, iY, iRowOffset, iColor, iR, iG, iB
- GdipGetImageDimension(hImage, @iW, @iH)
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Greyscale)
- GdipBitmapLockBits(hBitmap_Greyscale, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Greyscale)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- #define _Round2(x) ((x * 10000 + 0.5) / 100 Shr 0) / 100
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- iColor = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- iR = (iColor Shr 16) And &hFF
- iG = (iColor Shr 8) And &hFF
- iB = iColor And &hFF
- fLuma = (iR * 213 + iG * 715 + iB * 72) / 1000
- 'fLuma = ((iR * 0.3) + (iG * 0.59) + (iB * 0.11) / 3)
- fGreys = fLuma - Fix(fLuma)
- fLuma = Fix(fLuma)
- iR = 0
- iG = 0
- iB = 0
- Select Case _Round2(fGreys)
- Case 0.05 To 0.18
- iB = 1
- Case 0.19 To 0.34
- iG = 1
- Case 0.35 To 0.50
- iB = 1
- iG = 1
- Case 0.51 To 0.66
- iR = 1
- Case 0.67 To 0.82
- iR = 1
- iB = 1
- Case 0.83 To 0.95
- iR = 1
- iG = 1
- End Select
- Cast(ULong Ptr, tBitmapData_Greyscale.Scan0)[iRowOffset + iX] = &hFF000000 Or ((fLuma + iR) Shl 16) Or ((fLuma + iG) Shl 8) Or (fLuma + iB) Shl 0
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Greyscale, @tBitmapData_Greyscale)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Greyscale, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Greyscale)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Greyscale
- End Function
- Private Function _GDIPlus_BitmapCreateInverseGreyscale(hImage As Any Ptr, iThreshold As ULong) As Any Ptr 'based on original code by Jakub Szymanowski '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Inverse
- Dim As BitmapData tBitmapData, tBitmapData_Inverse
- Dim As Long iX, iY, iRowOffset, c, iDistance, iColor, iR, iG, iB
- GdipGetImageDimension(hImage, @iW, @iH)
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Inverse)
- GdipBitmapLockBits(hBitmap_Inverse, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Inverse)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- iColor = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- iR = (iColor Shr 16) And &hFF
- iG = (iColor Shr 8) And &hFF
- iB = iColor And &hFF
- c = CLng((iR * 213 + iG * 715 + iB * 72) / 1000)
- iDistance = Abs(iThreshold - c)
- If c >= iThreshold Then iColor = iThreshold - iDistance
- If c < iThreshold Then iColor = iThreshold + iDistance
- c = IIf(c > 255, 255, IIf(c < 0, 0, c))
- Cast(ULong Ptr, tBitmapData_Inverse.Scan0)[iRowOffset + iX] = &hFF000000 + c Shl 16 + c Shl 8 + c
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Inverse, @tBitmapData_Inverse)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- Return hBitmap_Inverse
- End Function
- Private Function _GDIPlus_BitmapCreateInverseBW(hImage As Any Ptr, iThreshold As UByte) As Any Ptr 'based on original code by Jakub Szymanowski '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_InverseBW
- Dim As BitmapData tBitmapData, tBitmapData_InverseBW
- Dim As Long iX, iY, iRowOffset, c, iColor, iR, iG, iB
- GdipGetImageDimension(hImage, @iW, @iH)
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_InverseBW)
- GdipBitmapLockBits(hBitmap_InverseBW, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_InverseBW)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- iThreshold = IIf(iThreshold < 1, 1, IIf(iThreshold > 254, 254, iThreshold))
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- iColor = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- iR = (iColor Shr 16) And &hFF
- iG = (iColor Shr 8) And &hFF
- iB = iColor And &hFF
- c = CLng(CLng((iR * 213 + iG * 715 + iB * 72) / 1000))
- If c > iThreshold Then
- iColor = &hFFFFFFFF
- Else
- iColor = &hFF000000
- EndIf
- Cast(ULong Ptr, tBitmapData_InverseBW.Scan0)[iRowOffset + iX] = iColor
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_InverseBW, @tBitmapData_InverseBW)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- Return hBitmap_InverseBW
- End Function
- Private Function _GDIPlus_BitmapCreateSubtract(hImage1 As Any Ptr, hImage2 As Any Ptr, iBias As Byte, bInvert As BOOL) As Any Ptr 'based on original code by Dewald Esterhuizen '...'
- Dim As Single iW1, iH1, iW2, iH2
- Dim As Any Ptr hBitmap_Subtract
- Dim As BitmapData tBitmapData1, tBitmapData2, tBitmapData_Subtract
- Dim As Long iX, iY, iRowOffset, iColor1, iColor2, iR, iG, iB
- GdipGetImageDimension(hImage1, @iW1, @iH1)
- GdipGetImageDimension(hImage2, @iW2, @iH2)
- If iW1 <> iW2 Or iH1 <> iH2 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW1 - 1, iH1 - 1)
- GdipCreateBitmapFromScan0(iW1, iH1, 0, PixelFormat32bppARGB, 0, @hBitmap_Subtract)
- GdipBitmapLockBits(hBitmap_Subtract, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Subtract)
- GdipBitmapLockBits(hImage1, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData1)
- GdipBitmapLockBits(hImage2, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData2)
- For iY = 0 To iH1 - 1
- iRowOffset = iY * iW1
- For iX = 0 To iW1 - 1
- iColor1 = Cast(ULong Ptr, tBitmapData1.Scan0)[iRowOffset + iX]
- iColor2 = Cast(ULong Ptr, tBitmapData2.Scan0)[iRowOffset + iX]
- If bInvert Then
- iR = &hFF - ((iColor1 Shr 16) And &hFF) - ((iColor2 Shr 16) And &hFF) + iBias
- iG = &hFF - ((iColor1 Shr 8) And &hFF) - ((iColor2 Shr 8) And &hFF) + iBias
- iB = &hFF - (iColor1 And &hFF) - (iColor2 And &hFF) + iBias
- Else
- iR = ((iColor1 Shr 16) And &hFF) - ((iColor2 Shr 16) And &hFF) + iBias
- iG = ((iColor1 Shr 8) And &hFF) - ((iColor2 Shr 8) And &hFF) + iBias
- iB = (iColor1 And &hFF) - (iColor2 And &hFF) + iBias
- EndIf
- iR = IIf(iR < 0, 0, IIf(iR > 255, 255, iR))
- iG = IIf(iG < 0, 0, IIf(iG > 255, 255, iG))
- iB = IIf(iB < 0, 0, IIf(iB > 255, 255, iB))
- Cast(ULong Ptr, tBitmapData_Subtract.Scan0)[iRowOffset + iX] = &hFF000000 + (iR Shl 16) + (iG Shl 8) + iB
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Subtract, @tBitmapData_Subtract)
- GdipBitmapUnlockBits(hImage1, @tBitmapData1)
- GdipBitmapUnlockBits(hImage2, @tBitmapData2)
- Return hBitmap_Subtract
- End Function
- Function _GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour(ByVal hImage As Any Ptr, fRadius As Single, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Dest, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Dest
- Dim As Long iX, iY, iRowOffset, c, k, sumR, sumG, sumB, iCount, xx, yy, iR, iG, iB, iR1, iG1, iB1, iR2, iG2, iB2, x, y
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect_dest = Type(0, 0, iW - 1, iH - 1), tRect = Type(0, 0, iW - 1, iH - 1)
- fRadius = IIf(fRadius < 1, 1, IIf(fRadius > 25, 25, fRadius))
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Dest)
- GdipBitmapLockBits(hBitmap_Dest, Cast(Any Ptr, @tRect_dest), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Dest)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- sumR = 0
- sumG = 0
- sumB = 0
- iCount = 0
- c = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- iR = (&h00FF0000 And c) Shr 16
- iG = (&h0000FF00 And c) Shr 8
- iB = &h000000FF And c
- For yy = -fRadius To fRadius
- For xx = -fRadius To fRadius
- k = iX + xx
- x = IIf(k < 0, 0, IIf(k > iW - 1, iW - 1, k))
- k = iY + yy
- y = IIf(k < 0, 0, IIf(k > iH - 1, iH - 1, k))
- c = Cast(ULong Ptr, tBitmapData.Scan0)[y * iW + x]
- iR1 = (&h00FF0000 And c) Shr 16
- iG1 = (&h0000FF00 And c) Shr 8
- iB1 = &h000000FF And c
- k = iX - xx
- x = IIf(k < 0, 0, IIf(k > iW - 1, iW - 1, k))
- k = iY + yy
- y = IIf(k < 0, 0, IIf(k > iH - 1, iH - 1, k))
- c = Cast(ULong Ptr, tBitmapData.Scan0)[y * iW + x]
- iR2 = (&h00FF0000 And c) Shr 16
- iG2 = (&h0000FF00 And c) Shr 8
- iB2 = &h000000FF And c
- If __DeltaE(iR, iG, iB, iR1, iG1, iB1) < __DeltaE(iR, iG, iB, iR2, iG2, iB2) Then
- sumR += iR1
- sumG += iG1
- sumB += iB1
- Else
- sumR += iR2
- sumG += iG2
- sumB += iB2
- EndIf
- iCount += 1
- Next
- Next
- Cast(ULong Ptr, tBitmapData_Dest.Scan0)[iRowOffset + iX] = &hFF000000 + Int(sumR / iCount) * &h10000 + Int(sumG / iCount) * &h100 + Int(sumB / iCount)
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Dest, @tBitmapData_Dest)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Dest, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Dest)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Dest
- End Function
- Function _GDIPlus_BitmapApplyFilter_Jitter(ByVal hImage As Any Ptr, iAmount As ULong, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Dest, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Dest
- Dim As Long iX, iY, iRowOffset, fNX, fNY, iColor
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect_dest = Type(0, 0, iW - 1, iH - 1), tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Dest)
- GdipBitmapLockBits(hBitmap_Dest, Cast(Any Ptr, @tRect_dest), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Dest)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- iAmount = IIF(iAmount < 1, 1, iAmount)
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- fNX = iX + Int((Rnd - 0.5) * iAmount)
- fNX = IIf(fNX < 1, 1, IIf(fNX > iW - 1, iW - 1, fNX))
- fNY = (iY + Int((Rnd - 0.5) * iAmount))
- fNY = IIf(fNY < 1, 1, IIf(fNY > iH - 1, iH - 1, fNY))
- fNY *= iW
- iColor = Cast(ULong Ptr, tBitmapData.Scan0)[fNY + fNX]
- Cast(ULong Ptr, tBitmapData_Dest.Scan0)[iRowOffset + iX] = iColor
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Dest, @tBitmapData_Dest)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Dest, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Dest)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Dest
- End Function
- Function _GDIPlus_BitmapApplyFilter_Median(ByVal hImage As Any Ptr, fRadius As Single, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Median, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Median
- Dim As Integer iX, iY, iRowOffset, iColor, iXX, iYY, iColors, iSize, iOff, iMid, iMedianR, iMedianG, iMedianB, iSizeArray
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Median)
- GdipBitmapLockBits(hBitmap_Median, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Median)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- fRadius = Int(IIf(fRadius < 1, 1, IIf(fRadius > 25, 25, fRadius)))
- iSizeArray = (2 * fRadius + 1) * (2 * fRadius + 1)
- ReDim aColorsR(0 To iSizeArray) As Integer
- ReDim aColorsG(0 To iSizeArray) As Integer
- ReDim aColorsB(0 To iSizeArray) As Integer
- iSize = iW * iH - 1
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- 'calculate median Values
- iColors = 0
- For iXX = iX - fRadius To iX + fRadius
- For iYY = iY - fRadius To iY + fRadius
- iOff = iYY * iW + iXX
- iColor = Cast(ULong Ptr, tBitmapData.Scan0)[IIf(iOff < 0, 0, IIf(iOff > iSize, iSize, iOff))]
- aColorsR(iColors) = (iColor Shr 16) And &hFF
- aColorsG(iColors) = (iColor Shr 8) And &hFF
- aColorsB(iColors) = iColor And &hFF
- iColors += 1
- Next
- Next
- 'sort array
- qsort(@aColorsR(0), iColors, SizeOf(Integer), cast(any ptr, @QCompare))
- qsort(@aColorsG(0), iColors, SizeOf(Integer), cast(any ptr, @QCompare))
- qsort(@aColorsB(0), iColors, SizeOf(Integer), cast(any ptr, @QCompare))
- iMid = Int(iColors / 2)
- If (iColors And 1) Then
- iMedianR = Int(aColorsR(iMid + 1))
- iMedianG = Int(aColorsG(iMid + 1))
- iMedianB = Int(aColorsB(iMid + 1))
- Else
- iMedianR = Int((aColorsR(iMid) + aColorsR(iMid + 1)) / 2)
- iMedianG = Int((aColorsG(iMid) + aColorsG(iMid + 1)) / 2)
- iMedianB = Int((aColorsB(iMid) + aColorsB(iMid + 1)) / 2)
- EndIf
- 'write median color values to bitmap
- Cast(ULong Ptr, tBitmapData_Median.Scan0)[iRowOffset + iX] = &hFF000000 + iMedianR Shl 16 + iMedianG Shl 8 + iMedianB
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Median, @tBitmapData_Median)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Median, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Median)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Median
- End Function
- Function _GDIPlus_BitmapApplyFilter_Median2(ByVal hImage As Any Ptr, fRadius As Single, bGDI As BOOL) As Any Ptr Export 'based on original code by Dewald Esterhuizen '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Median2, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Median2
- Dim As Long iX, iY, iRowOffset, iColor, iXX, iYY, iColors, iSize, iOff, iMid, iMedian, iSizeArray, filterOffset
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Median2)
- GdipBitmapLockBits(hBitmap_Median2, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Median2)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- fRadius = Int(IIf(fRadius < 1, 1, IIf(fRadius > 25, 25, fRadius)))
- iSizeArray = (2 * fRadius + 1) * (2 * fRadius + 1)
- ReDim aColors(0 To iSizeArray) As Integer
- iSize = iW * iH - 1
- filterOffset = (fRadius - 1) / 2
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- 'calculate median Values
- iColors = 0
- For iXX = iX - filterOffset To iX + filterOffset
- For iYY = iY - filterOffset To iY + filterOffset
- iOff = iYY * iW + iXX
- iColor = Cast(ULong Ptr, tBitmapData.Scan0)[IIf(iOff < 0, 0, IIf(iOff > iSize, iSize, iOff))]
- aColors(iColors) = iColor
- iColors += 1
- Next
- Next
- 'sort array
- qsort @aColors(0), iColors, SizeOf(Integer), cast(any ptr, @QCompare)
- iMedian = Int(aColors(filterOffset))
- 'write median color values to bitmap
- Cast(ULong Ptr, tBitmapData_Median2.Scan0)[iRowOffset + iX] = iMedian
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Median2, @tBitmapData_Median2)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Median2, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Median2)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Median2
- End Function
- Function _GDIPlus_BitmapApplyFilter_Kuwahara(ByVal hImage As Any Ptr, iSize As ULong, bGDI As BOOL) As Any Ptr Export 'based on code on http://www.gutgames.com/post/Kuwahara-Filter-in-C.aspx '...'
- Dim As Single ApetureMinX(0 To 3), ApetureMaxX(0 To 3), ApetureMinY(0 To 3), ApetureMaxY(0 To 3)
- Dim As Long RValues(0 To 3), GValues(0 To 3), BValues(0 To 3), NumPixels(0 To 3), MaxRValue(0 To 3), MaxGValue(0 To 3), MaxBValue(0 To 3), _
- MinRValue(0 To 3), MinGValue(0 To 3), MinBValue(0 To 3)
- Dim As Long iX, iY, TempX, TempY, x2, y2, i, j, MinDifference, CurrentDifference
- Dim As Long TempColor, r, g, b
- Dim As Any Ptr hBitmap_Kuwahara, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Kuwahara
- Dim As Single iW, iH
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- ApetureMinX(0) = -(iSize / 2)
- ApetureMinX(1) = 0
- ApetureMinX(2) = -(iSize / 2)
- ApetureMinX(3) = 0
- ApetureMaxX(0) = 0
- ApetureMaxX(1) = (iSize / 2)
- ApetureMaxX(2) = 0
- ApetureMaxX(3) = (iSize / 2)
- ApetureMinY(0) = -(iSize / 2)
- ApetureMinY(1) = -(iSize / 2)
- ApetureMinY(2) = 0
- ApetureMinY(3) = 0
- ApetureMaxY(0) = 0
- ApetureMaxY(1) = 0
- ApetureMaxY(2) = (iSize / 2)
- ApetureMaxY(3) = (iSize / 2)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Kuwahara)
- GdipBitmapLockBits(hBitmap_Kuwahara, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Kuwahara)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- For iX = 0 To iW - 1
- For iY = 0 To iH - 1
- RValues(0) = 0
- RValues(1) = 0
- RValues(2) = 0
- RValues(3) = 0
- GValues(0) = 0
- GValues(1) = 0
- GValues(2) = 0
- GValues(3) = 0
- BValues(0) = 0
- BValues(1) = 0
- BValues(2) = 0
- BValues(3) = 0
- NumPixels(0) = 0
- NumPixels(1) = 0
- NumPixels(2) = 0
- NumPixels(3) = 0
- MaxRValue(0) = 0
- MaxRValue(1) = 0
- MaxRValue(2) = 0
- MaxRValue(3) = 0
- MaxGValue(0) = 0
- MaxGValue(1) = 0
- MaxGValue(2) = 0
- MaxGValue(3) = 0
- MaxBValue(0) = 0
- MaxBValue(1) = 0
- MaxBValue(2) = 0
- MaxBValue(3) = 0
- MinRValue(0) = 255
- MinRValue(1) = 255
- MinRValue(2) = 255
- MinRValue(3) = 255
- MinGValue(0) = 255
- MinGValue(1) = 255
- MinGValue(2) = 255
- MinGValue(3) = 255
- MinBValue(0) = 255
- MinBValue(1) = 255
- MinBValue(2) = 255
- MinBValue(3) = 255
- For i = 0 To 3
- For x2 = ApetureMinX(i) To ApetureMaxX(i)
- TempX = iX + x2
- If (TempX >= 0) And (TempX < iW) Then
- For y2 = ApetureMinY(i) To ApetureMaxY(i)
- TempY = iY + y2
- If (TempY >= 0) And (TempY < iH) Then
- TempColor = Cast(ULong Ptr, tBitmapData.Scan0)[(TempY * iW) + TempX]
- r = (TempColor Shr 16) And &hFF
- g = (TempColor Shr 8) And &hFF
- b = TempColor And &hFF
- RValues(i) += r
- GValues(i) += g
- BValues(i) += b
- If r > MaxRValue(i) Then
- MaxRValue(i) = r
- ElseIf r < MinRValue(i) Then
- MinRValue(i) = r
- End If
- If g > MaxGValue(i) Then
- MaxGValue(i) = g
- ElseIf g < MinGValue(i) Then
- MinGValue(i) = g
- End If
- If b > MaxBValue(i) Then
- MaxBValue(i) = b
- ElseIf b < MinBValue(i) Then
- MinBValue(i) = b
- End If
- NumPixels(i) += 1
- End If
- Next
- End If
- Next
- Next
- j = 0
- MinDifference = 10000
- For i = 0 To 3
- CurrentDifference = (MaxRValue(i) - MinRValue(i)) + (MaxGValue(i) - MinGValue(i)) + (MaxBValue(i) - MinBValue(i))
- If (CurrentDifference < MinDifference) And (NumPixels(i) > 0) Then
- j = i
- MinDifference = CurrentDifference
- EndIf
- Next
- r = Int(RValues(j) / NumPixels(j)) Shl 16
- g = Int(GValues(j) / NumPixels(j)) Shl 8
- b = Int(BValues(j) / NumPixels(j))
- Cast(ULong Ptr, tBitmapData_Kuwahara.Scan0)[iY * iW + iX] = &hFF000000 + r + g + b
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Kuwahara, @tBitmapData_Kuwahara)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Kuwahara, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Kuwahara)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Kuwahara
- End Function
- Function _GDIPlus_BitmapApplyFilter_Edges(ByVal hImage As Any Ptr, bMode As UByte, bInverse As BOOL, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Dest, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Dest
- Dim As Long iX, iY, iRowOffset, c, cL, iR, iG, iB, iRl, iGl, iBl, iDiff, iRGB
- Dim As Single fBrightness, fBrightnessL
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect_dest = Type(0, 0, iW - 1, iH - 1), tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Dest)
- GdipBitmapLockBits(hBitmap_Dest, Cast(Any Ptr, @tRect_dest), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Dest)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 1 To iW - 1
- c = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- iR = (&h00FF0000 And c) Shr 16
- iG = (&h0000FF00 And c) Shr 8
- iB = &h000000FF And c
- fBrightness = Sqr(0.299 * iR * iR + 0.587 * iG * iG + 0.114 * iB * iB) 'luminance method
- cL = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX - 1]
- iRl = (&h00FF0000 And cL) Shr 16
- iGl = (&h0000FF00 And cL) Shr 8
- iBl = &h000000FF And cL
- fBrightnessL = Sqr(0.299 * iRl * iRl + 0.587 * iGl * iGl + 0.114 * iBl * iBl) 'luminance method
- Select Case bMode
- Case 0
- iDiff = Int(Abs(fBrightness - fBrightnessL))
- Case Else
- iDiff = &h80 + Int(Abs(fBrightness - fBrightnessL))
- iDiff = IIf(iDiff > 255, 255, iDiff)
- End Select
- If bInverse Then
- iRGB = ((iDiff Shl 16) + (iDiff Shl 8) + iDiff) Xor &h00FFFFFF
- Else
- iRGB = (iDiff Shl 16) + (iDiff Shl 8) + iDiff
- EndIf
- Cast(ULong Ptr, tBitmapData_Dest.Scan0)[iRowOffset + iX] = (&hFF000000 + iRGB)
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Dest, @tBitmapData_Dest)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Dest, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Dest)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Dest
- End Function
- Function _GDIPlus_BitmapApplyFilter_Pointillism(ByVal hImage As Any Ptr, iRounds As ULong, iSize As ULong, iA As UByte, bBorder As BOOL, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Dest, hGDIBitmap, hBrush, hPen, hGfx
- Dim As Long i, iR, iG, iB, iARGB, iAlpha, iAlpha2
- Dim As Single fX, fY, iSize2
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Dest)
- GdipGetImageGraphicsContext(hBitmap_Dest, @hGfx)
- GdipSetSmoothingMode(hGfx, 4)
- GdipSetPixelOffsetMode(hGfx, 4)
- If iRounds < 1 Then iRounds = CLng(iW * iH / 12.5)
- iRounds = IIf(iRounds > 1000000, 1000000, iRounds)
- iSize = IIf(iSize < 1, 1, IIf(iSize > 512, 512, iSize))
- iA = IIf(iA < 1, 1, IIf(iA > 255, 255, iA))
- iAlpha = iA Shl 24
- iAlpha2 = (iA Shr 2) Shl 24
- GdipCreatePen1(iAlpha2, 1, 2, @hPen)
- iSize2 = iSize / 2
- For i = 1 To iRounds
- fX = Rnd * (iW - 1)
- fY = Rnd * (iH - 1)
- GdipBitmapGetPixel(hImage, fX, fY, @iARGB)
- GdipCreateSolidFill(iAlpha + (iARGB And &H00FFFFFF), @hBrush)
- GdipFillEllipse(hGfx, hBrush, fX - iSize2, fY - iSize2, iSize, iSize)
- If bBorder Then GdipDrawEllipse(hGfx, hPen, fX - iSize2, fY - iSize2, iSize, iSize)
- GdipDeleteBrush(hBrush)
- Next
- GdipDeletePen(hPen)
- GdipDeleteGraphics(hGfx)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Dest, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Dest)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Dest
- End Function
- Function _GDIPlus_BitmapApplyFilter_Linellism(ByVal hImage As Any Ptr, iRounds As ULong, iSize As ULong, iA As UByte, iMode As UByte, bBorder As BOOL, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Dest, hGDIBitmap, hBrush, hPen, hGfx
- Dim As Long i, iR, iG, iB, iARGB, iAlpha, iAlpha2
- Dim As Single fX, fY, iSize2, iSize4
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Dest)
- GdipGetImageGraphicsContext(hBitmap_Dest, @hGfx)
- GdipSetSmoothingMode(hGfx, 4)
- GdipSetPixelOffsetMode(hGfx, 4)
- If iRounds < 1 Then iRounds = CLng(iW * iH / iSize * 2)
- iRounds = IIf(iRounds > 1000000, 1000000, iRounds)
- iSize = IIf(iSize < 1, 1, IIf(iSize > 512, 512, iSize))
- iA = IIF(iA < 1, 1, IIf(iA > 255, 255, iA))
- iAlpha = iA Shl 24
- iAlpha2 = (iA Shr 2) Shl 24
- iMode = IIF(iMode < 1, 1, IIf(iMode > 3, 3, iMode))
- GdipCreatePen1(iAlpha2, 1, 2, @hPen)
- iSize2 = iSize / 2
- iSize4 = iSize / 4
- For i = 1 To iRounds
- fX = Rnd * (iW - 1)
- fY = Rnd * (iH - 1)
- GdipBitmapGetPixel(hImage, fX, fY, @iARGB)
- GdipCreateSolidFill(iAlpha + (iARGB And &h00FFFFFF), @hBrush)
- Select Case iMode
- Case 1
- GdipFillRectangle(hGfx, hBrush, fX, fY, iSize, iSize4)
- If bBorder Then GdipDrawRectangle(hGfx, hPen, fX - iSize2, fY - iSize2, iSize, iSize4)
- Case 2
- GdipFillRectangle(hGfx, hBrush, fX, fY, iSize4, iSize)
- If bBorder Then GdipDrawRectangle(hGfx, hPen, fX - iSize2, fY - iSize2, iSize4, iSize)
- Case 3
- Select Case Int(Rnd * 10)
- Case 0 to 4
- GdipFillRectangle(hGfx, hBrush, fX, fY, iSize4, iSize)
- If bBorder Then GdipDrawRectangle(hGfx, hPen, fX, fY, iSize4, iSize)
- Case Else
- GdipFillRectangle(hGfx, hBrush, fX - iSize2, fY, iSize, iSize4)
- If bBorder Then GdipDrawRectangle(hGfx, hPen, fX, fY, iSize, iSize4)
- End Select
- End Select
- GdipDeleteBrush(hBrush)
- Next
- GdipDeletePen(hPen)
- GdipDeleteGraphics(hGfx)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Dest, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Dest)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Dest
- End Function
- Function _GDIPlus_BitmapApplyFilter_Convolution(ByVal hImage As Any Ptr, fFactor As Single, fBias As Single, iMode As UByte, pMStruct As Any Ptr, iMatrix As UShort, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH, fRedSum, fGreenSum, fBlueSum, fSum, fMatrix, fW, fH, aFilter(), aFilter2(), f
- Dim As Single fRedSumX, fGreenSumX, fBlueSumX, fRedSumY, fGreenSumY, fBlueSumY, fMatrixX, fMatrixY
- Dim As Any Ptr hBitmap_Dest, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Dest
- Dim As Long iX, iY, iRowOffset, iColor, iR, iG, iB, filterWidth, filterHeight, filterX, filterY, imageX, imageY
- Dim As ULong iAlpha, iRGB, c
- Dim As Integer iStatus
- Dim As UShort i, j
- Dim As Single Ptr pMatrix = pMStruct
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect_dest = Type(0, 0, iW - 1, iH - 1), tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Dest)
- GdipBitmapLockBits(hBitmap_Dest, Cast(Any Ptr, @tRect_dest), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Dest)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- iAlpha = &hFF000000
- iMode = IIf(iMode < 0, 1, IIf(iMode > 31, 31, iMode))
- filterWidth = 3
- filterHeight = 3
- Select Case iMode
- Case 0 'manual matrix
- filterWidth = Sqr(iMatrix)
- filterHeight = filterWidth
- 'If (filterWidth And 1) <> 1 Or filterWidth ^ 2 <> iMatrix Or filterWidth < 3 Then Return 0
- If filterWidth ^ 2 <> iMatrix Or filterWidth < 3 Then Return 0
- ReDim aFilter(0 To filterWidth - 1, 0 To filterHeight - 1)
- j = -1
- For i = 0 To iMatrix - 1
- If i Mod filterWidth = 0 Then j += 1
- aFilter(j Mod filterHeight, i Mod filterWidth) = pMatrix[i]
- Next
- Case 1 'Emboss
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = 2.0
- aFilter(0, 1) = 0.0
- aFilter(0, 2) = 0.0
- aFilter(1, 0) = 0.0
- aFilter(1, 1) = -1.0
- aFilter(1, 2) = 0.0
- aFilter(2, 0) = 0.0
- aFilter(2, 1) = 0.0
- aFilter(2, 2) = -1.0
- Case 2 'Emboss45Degree Filter
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -1.0
- aFilter(0, 1) = -1.0
- aFilter(0, 2) = 0.0
- aFilter(1, 0) = -1.0
- aFilter(1, 1) = 0.0
- aFilter(1, 2) = 1.0
- aFilter(2, 0) = 0.0
- aFilter(2, 1) = 1.0
- aFilter(2, 2) = 1.0
- Case 3 'EmbossTopLeftBottomRight Filter
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -1.0
- aFilter(0, 1) = 0.0
- aFilter(0, 2) = 0.0
- aFilter(1, 0) = 0.0
- aFilter(1, 1) = 0.0
- aFilter(1, 2) = 0.0
- aFilter(2, 0) = 0.0
- aFilter(2, 1) = 0.0
- aFilter(2, 2) = 1.0
- Case 4 'IntenseEmboss Filter
- filterWidth = 5
- filterHeight = 5
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -1.0
- aFilter(0, 1) = -1.0
- aFilter(0, 2) = -1.0
- aFilter(0, 3) = -1.0
- aFilter(0, 4) = 0.0
- aFilter(1, 0) = -1.0
- aFilter(1, 1) = -1.0
- aFilter(1, 2) = -1.0
- aFilter(1, 3) = 0.0
- aFilter(1, 4) = 1.0
- aFilter(2, 0) = -1.0
- aFilter(2, 1) = -1.0
- aFilter(2, 2) = 0.0
- aFilter(2, 3) = 1.0
- aFilter(2, 4) = 1.0
- aFilter(3, 0) = -1.0
- aFilter(3, 1) = 0.0
- aFilter(3, 2) = 1.0
- aFilter(3, 3) = 1.0
- aFilter(3, 4) = 1.0
- aFilter(4, 0) = 0.0
- aFilter(4, 1) = 1.0
- aFilter(4, 2) = 1.0
- aFilter(4, 3) = 1.0
- aFilter(4, 4) = 1.0
- Case 5 'Sharpen
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = 0
- aFilter(0, 1) = -1
- aFilter(0, 2) = 0
- aFilter(1, 0) = -1
- aFilter(1, 1) = 5
- aFilter(1, 2) = -1
- aFilter(2, 0) = 0
- aFilter(2, 1) = -1
- aFilter(2, 2) = 0
- Case 6 'Box blur (normalized)
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = 1
- aFilter(0, 1) = 1
- aFilter(0, 2) = 1
- aFilter(1, 0) = 1
- aFilter(1, 1) = 1
- aFilter(1, 2) = 1
- aFilter(2, 0) = 1
- aFilter(2, 1) = 1
- aFilter(2, 2) = 1
- Case 7 'Gaussian blur (approximation)
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = 1
- aFilter(0, 1) = 2
- aFilter(0, 2) = 1
- aFilter(1, 0) = 2
- aFilter(1, 1) = 4
- aFilter(1, 2) = 2
- aFilter(2, 0) = 1
- aFilter(2, 1) = 2
- aFilter(2, 2) = 1
- Case 8 'Triangle Blur
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = 1
- aFilter(0, 1) = 2
- aFilter(0, 2) = 1
- aFilter(1, 0) = 2
- aFilter(1, 1) = 4
- aFilter(1, 2) = 2
- aFilter(2, 0) = 1
- aFilter(2, 1) = 2
- aFilter(2, 2) = 1
- Case 9 'Unsharp (with no image mask) 5×5
- filterWidth = 5
- filterHeight = 5
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -1 / 256
- aFilter(0, 1) = -1 / 256 * 4
- aFilter(0, 2) = -1 / 256 * 6
- aFilter(0, 3) = -1 / 256 * 4
- aFilter(0, 4) = -1 / 256 * 1
- aFilter(1, 0) = -1 / 256 * 4
- aFilter(1, 1) = -1 / 256 * 16
- aFilter(1, 2) = -1 / 256 * 24
- aFilter(1, 3) = -1 / 256 * 16
- aFilter(1, 4) = -1 / 256 * 4
- aFilter(2, 0) = -1 / 256 * 6
- aFilter(2, 1) = -1 / 256 * 24
- aFilter(2, 2) = -1 / 256 * -476
- aFilter(2, 3) = -1 / 256 * 24
- aFilter(2, 4) = -1 / 256 * 6
- aFilter(3, 0) = -1 / 256 * 4
- aFilter(3, 1) = -1 / 256 * 16
- aFilter(3, 2) = -1 / 256 * 24
- aFilter(3, 3) = -1 / 256 * 16
- aFilter(3, 4) = -1 / 256 * 4
- aFilter(4, 0) = -1 / 256
- aFilter(4, 1) = -1 / 256 * 4
- aFilter(4, 2) = -1 / 256 * 6
- aFilter(4, 3) = -1 / 256 * 4
- aFilter(4, 4) = -1 / 256
- Case 10 'Unsharpen
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -1
- aFilter(0, 1) = -1
- aFilter(0, 2) = -1
- aFilter(1, 0) = -1
- aFilter(1, 1) = 9
- aFilter(1, 2) = -1
- aFilter(2, 0) = -1
- aFilter(2, 1) = -1
- aFilter(2, 2) = -1
- Case 11 'Edge Detection 1
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -0.125
- aFilter(0, 1) = -0.125
- aFilter(0, 2) = -0.125
- aFilter(1, 0) = -0.125
- aFilter(1, 1) = 1
- aFilter(1, 2) = -0.125
- aFilter(2, 0) = -0.125
- aFilter(2, 1) = -0.125
- aFilter(2, 2) = -0.125
- Case 12 'Edge Detection 2
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -1
- aFilter(0, 1) = -1
- aFilter(0, 2) = -1
- aFilter(1, 0) = -1
- aFilter(1, 1) = 8
- aFilter(1, 2) = -1
- aFilter(2, 0) = -1
- aFilter(2, 1) = -1
- aFilter(2, 2) = -1
- Case 13 'Edge Detection 3
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -5
- aFilter(0, 1) = 0
- aFilter(0, 2) = 0
- aFilter(1, 0) = 0
- aFilter(1, 1) = 0
- aFilter(1, 2) = 0
- aFilter(2, 0) = 0
- aFilter(2, 1) = 0
- aFilter(2, 2) = 5
- Case 14 'Edge Detection 4
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -1
- aFilter(0, 1) = -1
- aFilter(0, 2) = -1
- aFilter(1, 0) = 0
- aFilter(1, 1) = 0
- aFilter(1, 2) = 0
- aFilter(2, 0) = 1
- aFilter(2, 1) = 1
- aFilter(2, 2) = 1
- Case 15 'Edge Detection 5
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -1
- aFilter(0, 1) = -1
- aFilter(0, 2) = -1
- aFilter(1, 0) = 2
- aFilter(1, 1) = 2
- aFilter(1, 2) = 2
- aFilter(2, 0) = -1
- aFilter(2, 1) = -1
- aFilter(2, 2) = -1
- Case 16 'Edge Detection 6
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -5
- aFilter(0, 1) = -5
- aFilter(0, 2) = -5
- aFilter(1, 0) = -5
- aFilter(1, 1) = 39
- aFilter(1, 2) = -5
- aFilter(2, 0) = -5
- aFilter(2, 1) = -5
- aFilter(2, 2) = -5
- Case 17 'Another Blur
- filterWidth = 5
- filterHeight = 5
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = 0
- aFilter(0, 1) = 0
- aFilter(0, 2) = 1
- aFilter(0, 3) = 0
- aFilter(0, 4) = 0
- aFilter(1, 0) = 0
- aFilter(1, 1) = 1
- aFilter(1, 2) = 1
- aFilter(1, 3) = 1
- aFilter(1, 4) = 0
- aFilter(2, 0) = 1
- aFilter(2, 1) = 1
- aFilter(2, 2) = 1
- aFilter(2, 3) = 1
- aFilter(2, 4) = 1
- aFilter(3, 0) = 0
- aFilter(3, 1) = 1
- aFilter(3, 2) = 1
- aFilter(3, 3) = 1
- aFilter(3, 4) = 0
- aFilter(4, 0) = 0
- aFilter(4, 1) = 0
- aFilter(4, 2) = 1
- aFilter(4, 3) = 0
- aFilter(4, 4) = 0
- Case 18 'Motion Blur
- filterWidth = 9
- filterHeight = 9
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = 1
- aFilter(0, 1) = 0
- aFilter(0, 2) = 0
- aFilter(0, 3) = 0
- aFilter(0, 4) = 0
- aFilter(0, 5) = 0
- aFilter(0, 6) = 0
- aFilter(0, 7) = 0
- aFilter(0, 8) = 0
- aFilter(1, 0) = 0
- aFilter(1, 1) = 1
- aFilter(1, 2) = 0
- aFilter(1, 3) = 0
- aFilter(1, 4) = 0
- aFilter(1, 5) = 0
- aFilter(1, 6) = 0
- aFilter(1, 7) = 0
- aFilter(1, 8) = 0
- aFilter(2, 0) = 0
- aFilter(2, 1) = 0
- aFilter(2, 2) = 1
- aFilter(2, 3) = 0
- aFilter(2, 4) = 0
- aFilter(2, 5) = 0
- aFilter(2, 6) = 0
- aFilter(2, 7) = 0
- aFilter(2, 8) = 0
- aFilter(3, 0) = 0
- aFilter(3, 1) = 0
- aFilter(3, 2) = 0
- aFilter(3, 3) = 1
- aFilter(3, 4) = 0
- aFilter(3, 5) = 0
- aFilter(3, 6) = 0
- aFilter(3, 7) = 0
- aFilter(3, 8) = 0
- aFilter(4, 0) = 0
- aFilter(4, 1) = 0
- aFilter(4, 2) = 0
- aFilter(4, 3) = 0
- aFilter(4, 4) = 1
- aFilter(4, 5) = 0
- aFilter(4, 6) = 0
- aFilter(4, 7) = 0
- aFilter(4, 8) = 0
- aFilter(5, 0) = 0
- aFilter(5, 1) = 0
- aFilter(5, 2) = 0
- aFilter(5, 3) = 0
- aFilter(5, 4) = 0
- aFilter(5, 5) = 1
- aFilter(5, 6) = 0
- aFilter(5, 7) = 0
- aFilter(5, 8) = 0
- aFilter(6, 0) = 0
- aFilter(6, 1) = 0
- aFilter(6, 2) = 0
- aFilter(6, 3) = 0
- aFilter(6, 4) = 0
- aFilter(6, 5) = 0
- aFilter(6, 6) = 1
- aFilter(6, 7) = 0
- aFilter(6, 8) = 0
- aFilter(7, 0) = 0
- aFilter(7, 1) = 0
- aFilter(7, 2) = 0
- aFilter(7, 3) = 0
- aFilter(7, 4) = 0
- aFilter(7, 5) = 0
- aFilter(7, 6) = 0
- aFilter(7, 7) = 1
- aFilter(7, 8) = 0
- aFilter(8, 0) = 0
- aFilter(8, 1) = 0
- aFilter(8, 2) = 0
- aFilter(8, 3) = 0
- aFilter(8, 4) = 0
- aFilter(8, 5) = 0
- aFilter(8, 6) = 0
- aFilter(8, 7) = 0
- aFilter(8, 8) = 1
- Case 19 'Sharpen 2
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = 1
- aFilter(0, 1) = 1
- aFilter(0, 2) = 1
- aFilter(1, 0) = 1
- aFilter(1, 1) = -7
- aFilter(1, 2) = 1
- aFilter(2, 0) = 1
- aFilter(2, 1) = 1
- aFilter(2, 2) = 1
- Case 20 'Sobel Filter
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- ReDim aFilter2(0 To filterHeight - 1, 0 To filterWidth - 1)
- 'horizontal
- aFilter(0, 0) = 1
- aFilter(0, 1) = 2
- aFilter(0, 2) = 1
- aFilter(1, 0) = 0
- aFilter(1, 1) = 0
- aFilter(1, 2) = 0
- aFilter(2, 0) = -1
- aFilter(2, 1) = -2
- aFilter(2, 2) = -1
- 'vertical
- aFilter2(0, 0) = 1
- aFilter2(0, 1) = 0
- aFilter2(0, 2) = -1
- aFilter2(1, 0) = 2
- aFilter2(1, 1) = 0
- aFilter2(1, 2) = -2
- aFilter2(2, 0) = 1
- aFilter2(2, 1) = 0
- aFilter2(2, 2) = -1
- Case 21 'Laplace filter 3x3 v1
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = 0
- aFilter(0, 1) = -1
- aFilter(0, 2) = 0
- aFilter(1, 0) = -1
- aFilter(1, 1) = 4
- aFilter(1, 2) = -1
- aFilter(2, 0) = 0
- aFilter(2, 1) = -1
- aFilter(2, 2) = 0
- Case 22 'Laplace filter 3x3 v2
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -1
- aFilter(0, 1) = -1
- aFilter(0, 2) = -1
- aFilter(1, 0) = -1
- aFilter(1, 1) = 8
- aFilter(1, 2) = -1
- aFilter(2, 0) = -1
- aFilter(2, 1) = -1
- aFilter(2, 2) = -1
- Case 23 'Laplace filter 5x5
- filterWidth = 5
- filterHeight = 5
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -1
- aFilter(0, 1) = -1
- aFilter(0, 2) = -1
- aFilter(0, 3) = -1
- aFilter(0, 4) = -1
- aFilter(1, 0) = -1
- aFilter(1, 1) = -1
- aFilter(1, 2) = -1
- aFilter(1, 3) = -1
- aFilter(1, 4) = -1
- aFilter(2, 0) = -1
- aFilter(2, 1) = -1
- aFilter(2, 2) = 24
- aFilter(2, 3) = -1
- aFilter(2, 4) = -1
- aFilter(3, 0) = -1
- aFilter(3, 1) = -1
- aFilter(3, 2) = -1
- aFilter(3, 3) = -1
- aFilter(3, 4) = -1
- aFilter(4, 0) = -1
- aFilter(4, 1) = -1
- aFilter(4, 2) = -1
- aFilter(4, 3) = -1
- aFilter(4, 4) = -1
- Case 24 'Prewitt
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- ReDim aFilter2(0 To filterHeight - 1, 0 To filterWidth - 1)
- 'horizontal
- aFilter(0, 0) = -1
- aFilter(0, 1) = 0
- aFilter(0, 2) = 1
- aFilter(1, 0) = -1
- aFilter(1, 1) = 0
- aFilter(1, 2) = 1
- aFilter(2, 0) = -1
- aFilter(2, 1) = 0
- aFilter(2, 2) = 1
- 'vertical
- aFilter2(0, 0) = 1
- aFilter2(0, 1) = 1
- aFilter2(0, 2) = 1
- aFilter2(1, 0) = 0
- aFilter2(1, 1) = 0
- aFilter2(1, 2) = 0
- aFilter2(2, 0) = -1
- aFilter2(2, 1) = -1
- aFilter2(2, 2) = -1
- Case 25 'Kirsch
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- ReDim aFilter2(0 To filterHeight - 1, 0 To filterWidth - 1)
- 'horizontal
- aFilter(0, 0) = 5
- aFilter(0, 1) = 5
- aFilter(0, 2) = 5
- aFilter(1, 0) = -3
- aFilter(1, 1) = 0
- aFilter(1, 2) = -3
- aFilter(2, 0) = -3
- aFilter(2, 1) = -3
- aFilter(2, 2) = -3
- 'vertical
- aFilter2(0, 0) = 5
- aFilter2(0, 1) = -3
- aFilter2(0, 2) = -3
- aFilter2(1, 0) = 4
- aFilter2(1, 1) = 0
- aFilter2(1, 2) = -3
- aFilter2(2, 0) = 5
- aFilter2(2, 1) = -3
- aFilter2(2, 2) = -3
- Case 26 'Outline 3x3
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = -1
- aFilter(0, 1) = -1
- aFilter(0, 2) = -1
- aFilter(1, 0) = -1
- aFilter(1, 1) = 8
- aFilter(1, 2) = -1
- aFilter(2, 0) = -1
- aFilter(2, 1) = -1
- aFilter(2, 2) = -1
- Case 27 'Gaussian5x5 Type1 blur
- filterWidth = 5
- filterHeight = 5
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = 2
- aFilter(0, 1) = 4
- aFilter(0, 2) = 5
- aFilter(0, 3) = 4
- aFilter(0, 4) = 2
- aFilter(1, 0) = 4
- aFilter(1, 1) = 9
- aFilter(1, 2) = 12
- aFilter(1, 3) = 9
- aFilter(1, 4) = 4
- aFilter(2, 0) = 5
- aFilter(2, 1) = 12
- aFilter(2, 2) = 15
- aFilter(2, 3) = 12
- aFilter(2, 4) = 5
- aFilter(3, 0) = 4
- aFilter(3, 1) = 9
- aFilter(3, 2) = 12
- aFilter(3, 3) = 9
- aFilter(3, 4) = 4
- aFilter(4, 0) = 2
- aFilter(4, 1) = 4
- aFilter(4, 2) = 5
- aFilter(4, 3) = 4
- aFilter(4, 4) = 2
- Case 28 'Gaussian5x5 Type2 blur
- filterWidth = 5
- filterHeight = 5
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = 1
- aFilter(0, 1) = 4
- aFilter(0, 2) = 6
- aFilter(0, 3) = 4
- aFilter(0, 4) = 1
- aFilter(1, 0) = 4
- aFilter(1, 1) = 16
- aFilter(1, 2) = 24
- aFilter(1, 3) = 16
- aFilter(1, 4) = 4
- aFilter(2, 0) = 6
- aFilter(2, 1) = 24
- aFilter(2, 2) = 36
- aFilter(2, 3) = 24
- aFilter(2, 4) = 6
- aFilter(3, 0) = 4
- aFilter(3, 1) = 16
- aFilter(3, 2) = 24
- aFilter(3, 3) = 16
- aFilter(3, 4) = 4
- aFilter(4, 0) = 1
- aFilter(4, 1) = 4
- aFilter(4, 2) = 6
- aFilter(4, 3) = 4
- aFilter(4, 4) = 1
- Case 29 'Laplacian of Gaussian 5x5
- filterWidth = 5
- filterHeight = 5
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = 0
- aFilter(0, 1) = 0
- aFilter(0, 2) = -1
- aFilter(0, 3) = 0
- aFilter(0, 4) = 0
- aFilter(1, 0) = 0
- aFilter(1, 1) = -1
- aFilter(1, 2) = -2
- aFilter(1, 3) = -1
- aFilter(1, 4) = 0
- aFilter(2, 0) = -1
- aFilter(2, 1) = -2
- aFilter(2, 2) = 16
- aFilter(2, 3) = -2
- aFilter(2, 4) = -1
- aFilter(3, 0) = 0
- aFilter(3, 1) = -1
- aFilter(3, 2) = -2
- aFilter(3, 3) = -1
- aFilter(3, 4) = 0
- aFilter(4, 0) = 0
- aFilter(4, 1) = 0
- aFilter(4, 2) = -1
- aFilter(4, 3) = 0
- aFilter(4, 4) = 0
- Case 30 'SovelVsPrewitt 3x3
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- ReDim aFilter2(0 To filterHeight - 1, 0 To filterWidth - 1)
- 'horizontal -> Sobel h
- aFilter(0, 0) = 1
- aFilter(0, 1) = 2
- aFilter(0, 2) = 1
- aFilter(1, 0) = 0
- aFilter(1, 1) = 0
- aFilter(1, 2) = 0
- aFilter(2, 0) = -1
- aFilter(2, 1) = -2
- aFilter(2, 2) = -1
- 'vertical -> Prewitt v
- aFilter2(0, 0) = 1
- aFilter2(0, 1) = 1
- aFilter2(0, 2) = 1
- aFilter2(1, 0) = 0
- aFilter2(1, 1) = 0
- aFilter2(1, 2) = 0
- aFilter2(2, 0) = -1
- aFilter2(2, 1) = -1
- aFilter2(2, 2) = -1
- Case 31 'Gaussian3x3
- ReDim aFilter(0 To filterHeight - 1, 0 To filterWidth - 1)
- aFilter(0, 0) = 1
- aFilter(0, 1) = 2
- aFilter(0, 2) = 1
- aFilter(1, 0) = 2
- aFilter(1, 1) = 4
- aFilter(1, 2) = 2
- aFilter(2, 0) = 1
- aFilter(2, 1) = 2
- aFilter(2, 2) = 1
- End Select
- fW = filterWidth / 2
- fH = filterHeight / 2
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- fRedSum = 0.0
- fRedSumX = 0.0
- fRedSumY = 0.0
- fGreenSum = 0.0
- fGreenSumX = 0.0
- fGreenSumY = 0.0
- fBlueSum = 0.0
- fBlueSumX = 0.0
- fBlueSumY = 0.0
- fSum = 0.0
- For filterY = 0 To filterHeight - 1
- For filterX = 0 To filterWidth - 1
- imageX = Int(iX - fW + filterX + iW) Mod iW
- imageY = Int(iY - fH + filterY + iH) Mod iH
- c = Cast(ULong Ptr, tBitmapData.Scan0)[imageY * iW + imageX]
- iR = ((c Shr 16) And &hFF)
- iG = ((c Shr 8) And &hFF)
- iB = (c And &hFF)
- Select Case iMode
- Case 20, 24, 25, 30
- fMatrixX = aFilter(filterY, filterX)
- fMatrixY = aFilter2(filterY, filterX)
- fRedSumX += iR * fMatrixX
- fRedSumY += iR * fMatrixY
- fGreenSumX += iG * fMatrixX
- fGreenSumY += iG * fMatrixY
- fBlueSumX += iB * fMatrixX
- fBlueSumY += iB * fMatrixY
- fSum += (fMatrixX + fMatrixY)
- Case Else
- fMatrix = aFilter(filterY, filterX)
- fRedSum += iR * fMatrix
- fGreenSum += iG * fMatrix
- fBlueSum += iB * fMatrix
- fSum += fMatrix
- End Select
- Next
- Next
- fSum = IIf(fSum <= 0, 1.0, fSum)
- Select Case iMode
- Case 20, 24, 25, 30
- fRedSum = Sqr(fRedSumX * fRedSumX + fRedSumY * fRedSumY)
- fGreenSum = Sqr(fGreenSumX * fGreenSumX + fGreenSumY * fGreenSumY)
- fBlueSum = Sqr(fBlueSumX * fBlueSumX + fBlueSumY * fBlueSumY)
- Case Else
- End Select
- 'iRGB = Min(Max(Int(fFactor * fRedSum / fSum + fBias), 0), 255) Shl 16 + Min(Max(Int(fFactor * fGreenSum / fSum + fBias), 0), 255) Shl 8 + Min(Max(Int(fFactor * fBlueSum / fSum + fBias), 0), 255)
- iRGB = min(Abs(Int(fFactor * fRedSum / fSum + fBias)), 255) Shl 16 + _
- min(Abs(Int(fFactor * fGreenSum / fSum + fBias)), 255) Shl 8 + _
- min(Abs(Int(fFactor * fBlueSum / fSum + fBias)), 255)
- 'iRGB = Min(Abs(Int(fFactor * fRedSum + fBias)), 255) Shl 16 + Min(Abs(Int(fFactor * fGreenSum + fBias)), 255) Shl 8 + Min(Abs(Int(fFactor * fBlueSum + fBias)), 255)
- Cast(ULong Ptr, tBitmapData_Dest.Scan0)[iRowOffset + iX] = iAlpha + iRGB
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Dest, @tBitmapData_Dest)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Dest, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Dest)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Dest
- End Function
- Function _GDIPlus_BitmapApplyFilter_Raster(ByVal hImage As Any Ptr, iSizeW As ULong, iSizeH As ULong, fDensity As Single, fBrightness As Single, fBias As Single, iMode As Byte, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Any Ptr hBitmap_Raster, hGDIBitmap, hBitmap_BW, hBitmap_Grey, hBitmap_tmp, hBitmap_tmp2, hGfx, hGfx_tmp, hGfx_tmp2, hBrush
- Dim As Single iW, iH, fDen, fSizeW, fSizeH
- Dim As ULong iX, iY, iColor, iColor2, c, iWH
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- iSizeW = IIf(iSizeW < 3, 3, IIf(iSizeW > iW / 3, iW / 3, iSizeW))
- iSizeH = IIf(iSizeH < 3, 3, IIf(iSizeH > iH / 3, iH / 3, iSizeH))
- GdipCloneBitmapArea(0, 0, iW, iH, PixelFormat1bppIndexed, hImage, @hBitmap_BW)
- 'hBitmap_BW = _GDIPlus_BitmapCreateBW(hImage, &h60)
- hBitmap_Grey = _GDIPlus_BitmapCreateGreyscale(hImage)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Raster)
- GdipGetImageGraphicsContext(hBitmap_Raster, @hGfx)
- GdipSetSmoothingMode(hGfx, 4)
- GdipSetPixelOffsetMode(hGfx, 4)
- GdipGraphicsClear(hGfx, &hFFFFFFFF)
- GdipCreateBitmapFromScan0(iSizeW, iSizeH, 0, PixelFormat32bppARGB, 0, @hBitmap_tmp)
- GdipGetImageGraphicsContext(hBitmap_tmp, @hGfx_tmp)
- GdipCreateBitmapFromScan0(iSizeW, iSizeH, 0, PixelFormat32bppARGB, 0, @hBitmap_tmp2)
- GdipGetImageGraphicsContext(hBitmap_tmp2, @hGfx_tmp2)
- If iMode < 1 Then iMode = 1
- If fDensity < 0 Then fDensity = 0
- If fBrightness < 1 Then fBrightness = 1
- iWH = iSizeW * iSizeH
- For iY = 0 To iH - 1 Step iSizeH
- For iX = 0 To iW - 1 Step iSizeW
- GdipDrawImageRectRect(hGfx_tmp, hBitmap_Grey, 0, 0, iSizeW, iSizeH, iX, iY, iSizeW, iSizeH, 2, 0, 0, 0)
- GdipDrawImageRectRect(hGfx_tmp2, hImage, 0, 0, iSizeW, iSizeH, iX, iY, iSizeW, iSizeH, 2, 0, 0, 0)
- iColor = _GDIPlus_BitmapGetAverageColorValue(hBitmap_tmp, 1)
- iColor2 = _GDIPlus_BitmapGetAverageColorValue(hBitmap_tmp2, 0)
- If iMode = 1 Then
- GdipCreateSolidFill(iColor2, @hBrush)
- Else
- GdipCreateSolidFill(&hFF000000, @hBrush)
- End If
- c = (((iColor Shr 16) And &hFF) + ((iColor Shr 8) And &hFF) + (iColor And &hFF)) / fBrightness
- fDen = fDensity + c / iWH
- fSizeW = iSizeW * fDen
- fSizeW = IIf(fSizeW > iSizeW + fBias, iSizeW, fSizeW + fBias)
- fSizeH = iSizeH * fDen
- fSizeH = IIf(fSizeH > iSizeH + fBias, iSizeH, fSizeH + fBias)
- GdipFillEllipse(hGfx, hBrush, iX + (iSizeW - fSizeW) / 2, iY + (iSizeH - fSizeH) / 2, fSizeW, fSizeH)
- GdipDeleteBrush(hBrush)
- Next
- Next
- GdipDeleteGraphics(hGfx_tmp)
- GdipDisposeImage(hBitmap_tmp)
- GdipDeleteGraphics(hGfx_tmp2)
- GdipDisposeImage(hBitmap_tmp2)
- GdipDeleteGraphics(hGfx)
- 'GdipDisposeImage(hBitmap_BW)
- GdipDisposeImage(hBitmap_Grey)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Raster, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Raster)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Raster
- End Function
- Function _GDIPlus_BitmapApplyFilter_Rasterize(ByVal hImage As Any Ptr, iSpaceX As ULong, iSpaceY As ULong, iDelCol As ULong, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Any Ptr hBitmap_Rasterize, hGDIBitmap, hGfx_Rasterize, hBrush
- Dim As Single iW, iH
- Dim As ULong iX, iY
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- iSpaceX = IIf(iSpaceX < 2, 2, IIf(iSpaceX > iW - 1, iW - 1, iSpaceX))
- iSpaceY = IIf(iSpaceY < 2, 2, IIf(iSpaceY > iH - 1, iH - 1, iSpaceX))
- GdipCloneBitmapArea(0, 0, iW, iH, PixelFormat32bppARGB, hImage, @hBitmap_Rasterize)
- 'GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Rasterize)
- GdipGetImageGraphicsContext(hBitmap_Rasterize, @hGfx_Rasterize)
- 'GdipDrawImageRect(hGfx_Rasterize, hImage, 0, 0, iW, iH)
- GdipCreateSolidFill(iDelCol, @hBrush)
- For iX = 0 To iW - 1 Step iSpaceX
- GdipFillRectangle(hGfx_Rasterize, hBrush, iX, 0, iSpaceX - 1, iH)
- Next
- For iY = 0 To iH - 1 Step iSpaceY
- GdipFillRectangle(hGfx_Rasterize, hBrush, 0, iY, iW, iSpaceY - 1)
- Next
- GdipDeleteBrush(hBrush)
- GdipDeleteGraphics(hGfx_Rasterize)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Rasterize, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Rasterize)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Rasterize
- End Function
- Function _GDIPlus_BitmapApplyFilter_Pixelate(ByVal hImage As Any Ptr, iPixelate As UByte, bGrid As BOOL, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH, i
- Dim As ULong iNewW, iNewH
- Dim As Any Ptr hBitmap_scaled, hBitmap_pixelated, hGDIBitmap, hGfx, hPen
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- iPixelate = IIf(iPixelate < 2, 2, iPixelate)
- iNewW = CLng(iW / iPixelate)
- iNewH = CLng(iH / iPixelate)
- GdipCreateBitmapFromScan0(iNewW, iNewH, 0, PixelFormat32bppARGB, 0, @hBitmap_scaled)
- GdipGetImageGraphicsContext(hBitmap_scaled, @hGfx)
- GdipSetInterpolationMode(hGfx, 7)
- GdipDrawImageRect(hGfx, hImage, 0, 0, iNewW, iNewH)
- GdipDeleteGraphics(hGfx)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_pixelated)
- GdipGetImageGraphicsContext(hBitmap_pixelated, @hGfx)
- GdipSetInterpolationMode(hGfx, 5)
- GdipSetPixelOffsetMode(hGfx, 2)
- GdipDrawImageRectRect(hGfx, hBitmap_scaled, 0, 0, iW, iH, 0, 0, iNewW, iNewH, 2, 0, 0, 0)
- If bGrid Then
- GdipCreatePen1(&h80000000, 1, 2, @hPen)
- Dim As Single iStepW = iW / iNewW, iStepH = iH / iNewH
- For i = 0 To iW - 1 Step iStepW
- GdipDrawLine(hGfx, hPen, i, 0, i, iH)
- Next
- For i = 0 To iH - 1 Step iStepH
- GdipDrawLine(hGfx, hPen, 0, i, iW, i)
- Next
- GdipDeletePen(hPen)
- End If
- GdipDeleteGraphics(hGfx)
- GdipDisposeImage(hBitmap_scaled)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_pixelated, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_pixelated)
- Return hGDIBitmap
- EndIf
- Return hBitmap_pixelated
- End Function
- Function _GDIPlus_BitmapApplyFilter_Dilatation(ByVal hImage As Any Ptr, Size As UByte, bGDI As BOOL) As Any Ptr Export 'based on original code by Jakub Szymanowski '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Dilate, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Dilate
- Dim As Long iX, iY, x2, y2, TempX, TempY, TempColor, c, r, g, b, RValue, GValue, BValue, ApetureMin, ApetureMax
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Dilate)
- GdipBitmapLockBits(hBitmap_Dilate, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Dilate)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- Size = IIf(Size < 2, 2, IIf(Size > 32, 32, Size))
- ApetureMin = -(Size / 2)
- ApetureMax = (Size / 2)
- For iX = 0 To iW - 1
- For iY = 0 To iH - 1
- RValue = 0
- GValue = 0
- BValue = 0
- For x2 = ApetureMin To ApetureMax
- TempX = iX + x2
- If (TempX >= 0) And (TempX < iW) Then
- For y2 = ApetureMin To ApetureMax
- TempY = iY + y2
- If (TempY >= 0) And (TempY < iH) Then
- TempColor = Cast(ULong Ptr, tBitmapData.Scan0)[(TempY * iW) + TempX]
- r = (TempColor Shr 16) And &hFF
- g = (TempColor Shr 8) And &hFF
- b = TempColor And &hFF
- If r > RValue Then RValue = r
- If g > GValue Then GValue = g
- If b > BValue Then BValue = b
- End If
- Next
- End If
- Next
- Cast(ULong Ptr, tBitmapData_Dilate.Scan0)[iY * iW + iX] = &hFF000000 + RValue Shl 16 + GValue Shl 8 + BValue
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Dilate, @tBitmapData_Dilate)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Dilate, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Dilate)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Dilate
- End Function
- Function _GDIPlus_BitmapApplyFilter_Erosion(ByVal hImage As Any Ptr, Size As UByte, bGDI As BOOL) As Any Ptr Export 'based on original code by Jakub Szymanowski '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Erosion, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Erosion
- Dim As Long iX, iY, x2, y2, TempX, TempY, TempColor, c, r, g, b, RValue, GValue, BValue, ApetureMin, ApetureMax
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Erosion)
- GdipBitmapLockBits(hBitmap_Erosion, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Erosion)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- Size = IIf(Size < 2, 2, IIf(Size > 32, 32, Size))
- ApetureMin = -(Size / 2)
- ApetureMax = (Size / 2)
- For iX = 0 To iW - 1
- For iY = 0 To iH - 1
- RValue = &hFF
- GValue = &hFF
- BValue = &hFF
- For x2 = ApetureMin To ApetureMax
- TempX = iX + x2
- If (TempX >= 0) And (TempX < iW) Then
- For y2 = ApetureMin To ApetureMax
- TempY = iY + y2
- If (TempY >= 0) And (TempY < iH) Then
- TempColor = Cast(ULong Ptr, tBitmapData.Scan0)[(TempY * iW) + TempX]
- r = (TempColor Shr 16) And &hFF
- g = (TempColor Shr 8) And &hFF
- b = TempColor And &hFF
- If r < RValue Then RValue = r
- If g < GValue Then GValue = g
- If b < BValue Then BValue = b
- End If
- Next
- End If
- Next
- Cast(ULong Ptr, tBitmapData_Erosion.Scan0)[iY * iW + iX] = &hFF000000 + RValue Shl 16 + GValue Shl 8 + BValue
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Erosion, @tBitmapData_Erosion)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Erosion, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Erosion)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Erosion
- End Function
- Function _GDIPlus_BitmapApplyFilter_OilPainting(ByVal hImage As Any Ptr, iRadius As UByte, fIntensityLevels As Single, bGDI As BOOL) As Any Ptr Export 'based on original code by Santhosh G_ (http://www.codeproject.com/Articles/471994/OilPaintEffect) '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_OilPainting, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_OilPainting
- Dim As Long i, iX, iY, iX_O, iY_O, iR, iG, iB, iCurIntensity, iCurMax, iMaxIndex, iRowOffset
- Dim As Single aSumR(0 To 255), aSumG(0 To 255), aSumB(0 To 255), aIntensityCount(0 To 255)
- Dim As Const Single fI = fIntensityLevels / 255
- Dim As ULong TempColor, c
- Dim As Integer iStatus, iPosX, iPosY
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- iRadius = IIf(iRadius < 1, 1, IIf(iRadius > 32, 32, iRadius))
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_OilPainting)
- GdipBitmapLockBits(hBitmap_OilPainting, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_OilPainting)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- For iY_O = -iRadius To iRadius
- For iX_O = -iRadius To iRadius
- iPosX = Int((iX + iX_O) Mod iW)
- iPosY = Int((iY + iY_O) Mod iH)
- If iPosX < 0 Then iPosX = 0
- If iPosY < 0 Then iPosY = 0
- TempColor = Cast(ULong Ptr, tBitmapData.Scan0)[iPosY * iW + iPosX]
- iR = (TempColor Shr 16) And &hFF
- iG = (TempColor Shr 8) And &hFF
- iB = TempColor And &hFF
- iCurIntensity = (iR * 213 + iG * 715 + iB * 72) / 1000 * fI ' luminance method
- If iCurIntensity > 255 Then iCurIntensity = 255
- aIntensityCount(iCurIntensity) += 1
- aSumR(Int(iCurIntensity)) += iR
- aSumG(Int(iCurIntensity)) += iG
- aSumB(Int(iCurIntensity)) += iB
- Next
- Next
- iCurMax = 0
- iMaxIndex = 0
- For i = 0 To 255
- If aIntensityCount(i) > iCurMax Then
- iCurMax = aIntensityCount(i)
- iMaxIndex = i
- EndIf
- Next
- Cast(ULong Ptr, tBitmapData_OilPainting.Scan0)[iRowOffset + iX] = &hFF000000 + (aSumR(iMaxIndex) / iCurMax) Shl 16 + (aSumG(iMaxIndex) / iCurMax) Shl 8 + (aSumB(iMaxIndex) / iCurMax)
- For i = 0 To 255
- aIntensityCount(i) = 0
- aSumR(i) = 0
- aSumG(i) = 0
- aSumB(i) = 0
- Next
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_OilPainting, @tBitmapData_OilPainting)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_OilPainting, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_OilPainting)
- Return hGDIBitmap
- EndIf
- Return hBitmap_OilPainting
- End Function
- Function _GDIPlus_BitmapApplyFilter_ColorAccent(ByVal hImage As Any Ptr, iHue As UShort, fRange As Single, bGDI As BOOL) As Any Ptr Export 'based on original code by Jakub Szymanowski '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_ColorAccent, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_ColorAccent
- Dim As Long iX, iY, iRowOffset, c, iR, iG, iB
- Dim As Single fH, fCMax, fCMin, fDelta, fH1, fH2
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_ColorAccent)
- GdipBitmapLockBits(hBitmap_ColorAccent, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_ColorAccent)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- fH1 = (iHue - fRange / 2 + 360) Mod 360
- fH2 = (iHue + fRange / 2 + 360) Mod 360
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 1 To iW - 1
- c = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- iR = (c Shr 16) And &hFF
- iG = (c Shr 8) And &hFF
- iB = c And &hFF
- 'convert RGB to Hue value only
- fCMax = _Max3(iR, iG, iB)
- fCMin = _Min3(iR, iG, iB)
- fDelta = fCMax - fCMin
- If fDelta = 0 Then fH = 0
- If fCMax = iR Then fH = 60 * (((iG - iB) / fDelta) Mod 6)
- If fCMax = iG Then fH = 60 * (((iB - iR) / fDelta) + 2)
- If fCMax = iB Then fH = 60 * (((iR - iG) / fDelta) + 4)
- If fH1 <= fH2 Then
- If fH >= fH1 And fH <= fH2 Then
- Cast(ULong Ptr, tBitmapData_ColorAccent.Scan0)[iRowOffset + iX] = &hFF000000 + c
- Else
- c = Int((iR * 213 + iG * 715 + iB * 72) / 1000)
- Cast(ULong Ptr, tBitmapData_ColorAccent.Scan0)[iRowOffset + iX] = &hFF000000 + c Shl 16 + c Shl 8 + c
- EndIf
- Else
- If fH >= fH1 Or fH <= fH2 Then
- Cast(ULong Ptr, tBitmapData_ColorAccent.Scan0)[iRowOffset + iX] = &hFF000000 + c
- Else
- c = Int((iR * 213 + iG * 715 + iB * 72) / 1000)
- Cast(ULong Ptr, tBitmapData_ColorAccent.Scan0)[iRowOffset + iX] = &hFF000000 + c Shl 16 + c Shl 8 + c
- EndIf
- EndIf
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_ColorAccent, @tBitmapData_ColorAccent)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_ColorAccent, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_ColorAccent)
- Return hGDIBitmap
- EndIf
- Return hBitmap_ColorAccent
- End Function
- Function _GDIPlus_BitmapApplyFilter_PenSketch(ByVal hImage As Any Ptr, iThreshold As Single, bGDI As BOOL) As Any Ptr Export 'based on original code by Jakub Szymanowski '...'
- Dim As Any Ptr hBitmap_PenSketch, hBitmap_Greyscale, hBitmap_Edge, hBitmap_Negative, hBitmap_Blur, hGDIBitmap
- hBitmap_Greyscale = _GDIPlus_BitmapCreateGreyscale(hImage)
- hBitmap_Edge = _GDIPlus_BitmapApplyFilter_Convolution(hBitmap_Greyscale, 1.25, iThreshold, 20, 0, 0, 0)
- hBitmap_Negative = _GDIPlus_BitmapCreateNegative(hBitmap_Edge)
- hBitmap_Blur = _GDIPlus_BitmapApplyFilter_Convolution(hBitmap_Negative, 1.15, 0, 8, 0, 0, 0)
- hBitmap_PenSketch = _GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour(hBitmap_Blur, 6, 0)
- GdipDisposeImage(hBitmap_Greyscale)
- GdipDisposeImage(hBitmap_Edge)
- GdipDisposeImage(hBitmap_Negative)
- GdipDisposeImage(hBitmap_Blur)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_PenSketch, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_PenSketch)
- Return hGDIBitmap
- EndIf
- Return hBitmap_PenSketch
- End Function
- Function _GDIPlus_BitmapApplyFilter_PenSketch2(ByVal hImage As Any Ptr, iThreshold As UByte, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Any Ptr hBitmap_PenSketch2, hBitmap_Median, hBitmap_Median2, hBitmap_Edge, hBitmap_Inverse, hGDIBitmap
- hBitmap_Median = _GDIPlus_BitmapApplyFilter_Median(hImage, 4, 0)
- hBitmap_Edge = _GDIPlus_BitmapApplyFilter_Convolution(hBitmap_Median, 1, iThreshold, 20, 0, 0, 0)
- hBitmap_Inverse = _GDIPlus_BitmapCreateInverseGreyscale(hBitmap_Edge, 80)
- hBitmap_Median2 = _GDIPlus_BitmapApplyFilter_Median(hBitmap_Inverse, 3, 0)
- hBitmap_PenSketch2 = _GDIPlus_BitmapCreateNegative(hBitmap_Median2)
- GdipDisposeImage(hBitmap_Median)
- GdipDisposeImage(hBitmap_Edge)
- GdipDisposeImage(hBitmap_Inverse)
- GdipDisposeImage(hBitmap_Median2)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_PenSketch2, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_PenSketch2)
- Return hGDIBitmap
- EndIf
- Return hBitmap_PenSketch2
- End Function
- Function _GDIPlus_BitmapApplyFilter_Cartoon1(ByVal hImage As Any Ptr, iRadius As UByte, fIntensityLevels As Single, iThreshold As UByte, bGDI As BOOL) As Any Ptr Export 'based on original code by Jakub Szymanowski '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Cartoon1, hGDIBitmap, hBitmap_Oil, hBitmap_Edge, hBitmap_Sobel, hBitmap_Blur, hGfx, hPen
- Dim As BitmapData tBitmapData, tBitmapData_Edge, tBitmapData_Oil, tBitmapData_Cartoon1
- Dim As Long iX, iY, iRowOffset, cE, cO, iRed
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- hBitmap_Oil = _GDIPlus_BitmapApplyFilter_OilPainting(hImage, iRadius, fIntensityLevels, 0)
- hBitmap_Sobel = _GDIPlus_BitmapApplyFilter_Convolution(hImage, 1.0, 32, 20, 0, 0, 0)
- hBitmap_Blur = _GDIPlus_BitmapApplyFilter_Convolution(hBitmap_Sobel, 1, 0, 28, 0, 0, 0)
- hBitmap_Edge = _GDIPlus_BitmapCreateInverseBW(hBitmap_Blur, iThreshold)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Cartoon1)
- GdipBitmapLockBits(hBitmap_Cartoon1, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Cartoon1)
- GdipBitmapLockBits(hBitmap_Edge, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData_Edge)
- GdipBitmapLockBits(hBitmap_Oil, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData_Oil)
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 1 To iW - 1
- cE = Cast(ULong Ptr, tBitmapData_Edge.Scan0)[iRowOffset + iX]
- iRed = (cE Shr 16) And &hFF
- If iRed < &h80 Then
- cO = Cast(ULong Ptr, tBitmapData_Oil.Scan0)[iRowOffset + iX]
- Cast(ULong Ptr, tBitmapData_Cartoon1.Scan0)[iRowOffset + iX] = cO
- Else
- Cast(ULong Ptr, tBitmapData_Cartoon1.Scan0)[iRowOffset + iX] = cE Xor &h00FFFFFF
- EndIf
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Cartoon1, @tBitmapData_Cartoon1)
- GdipBitmapUnlockBits(hBitmap_Edge, @tBitmapData_Edge)
- GdipBitmapUnlockBits(hBitmap_Oil, @tBitmapData_Oil)
- GdipDisposeImage(hBitmap_Oil)
- GdipDisposeImage(hBitmap_Sobel)
- GdipDisposeImage(hBitmap_Edge)
- GdipDisposeImage(hBitmap_Blur)
- /'
- GdipGetImageGraphicsContext(hBitmap_Cartoon1, @hGfx)
- Dim As Single fSize, fRadius
- fSize = iRadius
- fRadius = fSize / 2
- GdipCreatePen1(&hFF000000, fSize, 2, @hPen)
- GdipDrawRectangle(hGfx, hPen, fRadius, fRadius, iW - fSize, iH - fSize)
- GdipDeletePen(hPen)
- GdipDeleteGraphics(hGfx)
- '/
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Cartoon1, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Cartoon1)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Cartoon1
- End Function
- Function _GDIPlus_BitmapApplyFilter_TiltShift(ByVal hImage As Any Ptr, fPosY_Start As Single, iIntensity As UByte, bGDI As BOOL) As Any Ptr Export 'based on original code by Jakub Szymanowski '...'
- Dim As Single iW, iH, fCounterR, fCounterG, fCounterB, fDominator, sigma, fPosY_End
- Dim As Double gauss, L, S
- Dim As Any Ptr hBitmap_TiltShift, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_TiltShift
- Dim As Long iStatus, iX, iY, k, b, y, y1, y2, newR, newG, newB, c, iARGB, iARGB1, iARGB2, iOffset
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_TiltShift)
- GdipBitmapLockBits(hBitmap_TiltShift, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_TiltShift)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- fPosY_End = (fPosY_Start + fPosY_Start / 2)
- If fPosY_End > iH Or fPosY_Start < 0 Then
- fPosY_Start = iH / 2
- fPosY_End = fPosY_Start + fPosY_Start / 2
- EndIf
- L = 0.5 'is defined function value for blurring in close proximity to sharp part (ex. in range 0.05 - 0.15)
- S = 6.5 'is defined function value for blurring in far proximity to sharp part (ex. in range 5 - 7)
- Dim Filter(0 To iIntensity) As Double
- For iY = 0 To iH - 1
- iOffset = iY * iW
- For iX = 0 To iW - 1
- If (iY >= fPosY_Start) And (iY <= fPosY_End) Then
- Cast(ULong Ptr, tBitmapData_TiltShift.Scan0)[iOffset + iX] = Cast(ULong Ptr, tBitmapData.Scan0)[iOffset + iX]
- Else
- If iY < fPosY_Start Then
- sigma = L + (S - L) * (fPosY_Start - iY) / fPosY_Start 'fPosY_Start - iY = is height of larger blurred field (in vertical blurring)
- ElseIf iY > fPosY_End Then 'fPosY_Start = is height of larger blurred field (in vertical blurring)
- sigma = L + (S - L) * (iY - fPosY_End) / fPosY_Start
- EndIf
- 'ReDim Filter(0 To iIntensity) As Double
- c = 0
- For k = 0 To iIntensity - 1
- gauss = (1 / (fPiSqr * sigma)) * Exp((-k * k) / (2 * sigma * sigma))
- If Not (gauss < 0.003) Then
- Filter(c) = gauss
- c += 1
- EndIf
- Next
- iARGB = Cast(ULong Ptr, tBitmapData.Scan0)[iOffset + iX]
- fCounterR = Filter(0) * ((iARGB Shr 16) And &hFF)
- fCounterG = Filter(0) * ((iARGB Shr 8) And &hFF)
- fCounterB = Filter(0) * (iARGB And &hFF)
- fDominator = Filter(0)
- For b = 1 To c - 1
- fDominator += 2 * Filter(b)
- y1 = iY - b
- y2 = iY + b
- If y1 < 0 Then
- y1 = Abs(y1)
- ElseIf y2 >= iH Then
- y2 = y2 + b - iH + 1
- Else
- iARGB1 = Cast(ULong Ptr, tBitmapData.Scan0)[y1 * iW + iX]
- iARGB2 = Cast(ULong Ptr, tBitmapData.Scan0)[y2 * iW + iX]
- fCounterR += Filter(b) * (((iARGB1 Shr 16) And &hFF) + ((iARGB2 Shr 16) And &hFF))
- fCounterG += Filter(b) * (((iARGB1 Shr 8) And &hFF) + ((iARGB2 Shr 8) And &hFF))
- fCounterB += Filter(b) * ((iARGB1 And &hFF) + (iARGB2 And &hFF))
- EndIf
- Next
- newR = Int(fCounterR / fDominator)
- newG = Int(fCounterG / fDominator)
- newB = Int(fCounterB / fDominator)
- newR = IIf(newR < 0, 0, IIf(newR > 255, 255, newR))
- newG = IIf(newG < 0, 0, IIf(newG > 255, 255, newG))
- newB = IIf(newB < 0, 0, IIf(newB > 255, 255, newB))
- Cast(ULong Ptr, tBitmapData_TiltShift.Scan0)[iOffset + iX] = &hFF000000 + (newR Shl 16) + (newG Shl 8) + newB
- End If
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_TiltShift, @tBitmapData_TiltShift)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_TiltShift, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_TiltShift)
- Return hGDIBitmap
- EndIf
- Return hBitmap_TiltShift
- End Function
- Function _GDIPlus_BitmapApplyFilter_RadialBlur(ByVal hImage As Any Ptr, fPosX As Single, fPosY As Single, fRadius As Single, iIntensity As UByte, bGDI As BOOL) As Any Ptr Export 'based on original code by Jakub Szymanowski '...'
- Dim As Single iW, iH, fCounterR, fCounterG, fCounterB, fDominator
- Dim As Double gauss, L, S, H, V, R, sigma
- Dim As Any Ptr hBitmap_RadialBlur, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_RadialBlur
- Dim As Long iStatus, iX, iY, k, b, y, y1, y2, newR, newG, newB, c, iARGB, iARGB1, iARGB2, iOffset
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_RadialBlur)
- GdipBitmapLockBits(hBitmap_RadialBlur, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_RadialBlur)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- L = 0.15 'is defined function value for blurring in close proximity to sharp part (ex. in range 0.05 - 0.15)
- S = 6.0 'is defined function value for blurring in far proximity to sharp part (ex. in range 5 - 7)
- Dim Filter(0 To iIntensity) As Double
- For iY = 0 To iH - 1
- iOffset = iY * iW
- For iX = 0 To iW - 1
- H = Abs(iX - fPosX)
- V = Abs(iY - fPosY)
- R = Sqr(H * H + V * V)
- If R < fRadius Then
- Cast(ULong Ptr, tBitmapData_RadialBlur.Scan0)[iOffset + iX] = Cast(ULong Ptr, tBitmapData.Scan0)[iOffset + iX]
- Else
- sigma = L + (S - L) * R / (2 * fRadius)
- c = 0
- For k = 0 To iIntensity - 1
- gauss = (1 / (fPiSqr * sigma)) * Exp((-k * k) / (2 * sigma * sigma))
- If Not (gauss < 0.003) Then
- Filter(c) = gauss
- c += 1
- EndIf
- Next
- iARGB = Cast(ULong Ptr, tBitmapData.Scan0)[iOffset + iX]
- fCounterR = Filter(0) * ((iARGB Shr 16) And &hFF)
- fCounterG = Filter(0) * ((iARGB Shr 8) And &hFF)
- fCounterB = Filter(0) * (iARGB And &hFF)
- fDominator = Filter(0)
- For b = 1 To c - 1
- fDominator += 2 * Filter(b)
- y1 = iY - b
- y2 = iY + b
- If y1 < 0 Then
- y1 = Abs(y1)
- ElseIf y2 >= iH Then
- y2 = y2 + b - iH + 1
- Else
- iARGB1 = Cast(ULong Ptr, tBitmapData.Scan0)[y1 * iW + iX]
- iARGB2 = Cast(ULong Ptr, tBitmapData.Scan0)[y2 * iW + iX]
- fCounterR += Filter(b) * (((iARGB1 Shr 16) And &hFF) + ((iARGB2 Shr 16) And &hFF))
- fCounterG += Filter(b) * (((iARGB1 Shr 8) And &hFF) + ((iARGB2 Shr 8) And &hFF))
- fCounterB += Filter(b) * ((iARGB1 And &hFF) + (iARGB2 And &hFF))
- EndIf
- Next
- newR = Int(fCounterR / fDominator)
- newG = Int(fCounterG / fDominator)
- newB = Int(fCounterB / fDominator)
- newR = IIf(newR < 0, 0, IIf(newR > 255, 255, newR))
- newG = IIf(newG < 0, 0, IIf(newG > 255, 255, newG))
- newB = IIf(newB < 0, 0, IIf(newB > 255, 255, newB))
- Cast(ULong Ptr, tBitmapData_RadialBlur.Scan0)[iOffset + iX] = &hFF000000 + (newR Shl 16) + (newG Shl 8) + newB
- End If
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_RadialBlur, @tBitmapData_RadialBlur)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_RadialBlur, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_RadialBlur)
- Return hGDIBitmap
- EndIf
- Return hBitmap_RadialBlur
- End Function
- Function _GDIPlus_BitmapApplyFilter_TimeWarp(ByVal hImage As Any Ptr, fFactor As Single, fMidX As Single, fMidY As Single, bGDI As BOOL) As Any Ptr Export 'based on original code on https://www.programmingalgorithms.com/algorithm/time-warp '...'
- Dim As Single iW, iH
- Dim As Integer iStatus
- Dim As Any Ptr hBitmap_TimeWarp, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_TimeWarp
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_TimeWarp)
- GdipBitmapLockBits(hBitmap_TimeWarp, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_TimeWarp)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- Dim As Integer iX, iY, iTrueX, iTrueY, iNewX, iNewY, iOffset
- Dim As Double fNewRadius, fTheta, fRadius
- For iY = 0 To iH - 1
- iOffset = iY * iW
- iTrueY = iY - fMidY
- For iX = 0 To iW - 1
- iTrueX = iX - fMidX
- fTheta = Atan2(iTrueY, iTrueX)
- fRadius = Sqr(iTrueX * iTrueX + iTrueY * iTrueY)
- fNewRadius = Sqr(fRadius) * fFactor
- iNewX = CLng(fMidX + (fNewRadius * Cos(fTheta)))
- iNewY = CLng(fMidY + (fNewRadius * Sin(fTheta)))
- If (iNewY >= 0 And iNewY < iH) And (iNewX >= 0 And iNewX < iW) Then
- Cast(ULong Ptr, tBitmapData_TimeWarp.Scan0)[iOffset + iX] = Cast(ULong Ptr, tBitmapData.Scan0)[iNewY * iW + iNewX]
- EndIf
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_TimeWarp, @tBitmapData_TimeWarp)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_TimeWarp, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_TimeWarp)
- Return hGDIBitmap
- EndIf
- Return hBitmap_TimeWarp
- End Function
- Function _GDIPlus_BitmapApplyFilter_FishEye(ByVal hImage As Any Ptr, bGDI As BOOL) As Any Ptr Export 'based on original code by Christian Graus on http://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part '...'
- Dim As Single iW, iH
- Dim As Integer iStatus
- Dim As Any Ptr hBitmap_FishEye, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_FishEye
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_FishEye)
- GdipBitmapLockBits(hBitmap_FishEye, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_FishEye)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- Dim As Integer i, iX, iY, iTrueX, iTrueY, iNewX, iNewY, iOffset
- Dim As Double fTheta, fRadius, fMidX, fMidY, fNewRadius
- fMidX = iW / 2
- fMidY = iH / 2
- Dim As Single fMaxXY
- fMaxXY = max(fMidX, fMidY)
- For iY = 0 To iH - 1
- iOffset = iY * iW
- iTrueY = iY - fMidY 'translate to center y
- For iX = 0 To iW - 1
- iTrueX = iX - fMidX 'translate to center x
- fTheta = Atan2(iTrueY, iTrueX)
- fRadius = Sqr(iTrueX * iTrueX + iTrueY * iTrueY)
- fNewRadius = fRadius * fRadius / fMaxXY
- iNewX = fMidX + (fNewRadius * Cos(fTheta))
- iNewY = fMidY + (fNewRadius * Sin(fTheta))
- If Not (iNewY >= 0 And iNewY < iH) And (iNewX >= 0 And iNewX < iW) Then
- iNewX = 0
- iNewY = 0
- EndIf
- If (iNewY >= 0 And iNewY < iH) And (iNewX >= 0 And iNewX < iW) Then
- Cast(ULong Ptr, tBitmapData_FishEye.Scan0)[iOffset + iX] = Cast(ULong Ptr, tBitmapData.Scan0)[iNewY * iW + iNewX]
- EndIf
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_FishEye, @tBitmapData_FishEye)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_FishEye, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_FishEye)
- Return hGDIBitmap
- EndIf
- Return hBitmap_FishEye
- End Function
- Function _GDIPlus_BitmapApplyFilter_Wave(ByVal hImage As Any Ptr, fAmplitudeX As Single, fAmplitudeY As Single, fFrequencyX As Single, fFrequencyY As Single, bGDI As BOOL) As Any Ptr Export 'based on original code by Christian Graus on http://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part '...'
- Dim As Single iW, iH
- Dim As Integer iStatus
- Dim As Any Ptr hBitmap_Wave, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Wave
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Wave)
- GdipBitmapLockBits(hBitmap_Wave, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Wave)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- Dim As Integer i, iX, iY, iTrueX, iTrueY, iNewX, iNewY, iOffset
- For iY = 0 To iH - 1
- iOffset = iY * iW
- iTrueX = fAmplitudeX * Sin(f2Pi * iY / fFrequencyX)
- For iX = 0 To iW - 1
- iTrueY = fAmplitudeY * Cos(f2Pi * iX / fFrequencyY)
- iNewX = iX + iTrueX
- iNewY = iY + iTrueY
- If (iNewY >= 0 And iNewY < iH) And (iNewX >= 0 And iNewX < iW) Then
- Cast(ULong Ptr, tBitmapData_Wave.Scan0)[iOffset + iX] = Cast(ULong Ptr, tBitmapData.Scan0)[iNewY * iW + iNewX]
- EndIf
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Wave, @tBitmapData_Wave)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Wave, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Wave)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Wave
- End Function
- Function _GDIPlus_BitmapApplyFilter_Swirl(ByVal hImage As Any Ptr, fDegree As Single, bGDI As BOOL) As Any Ptr Export 'based on original code by Christian Graus on http://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part '...'
- Dim As Single iW, iH
- Dim As Integer iStatus
- Dim As Any Ptr hBitmap_Swirl, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Swirl
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Swirl)
- GdipBitmapLockBits(hBitmap_Swirl, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Swirl)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- Dim As Integer i, iX, iY, iTrueX, iTrueY, iNewX, iNewY, iOffset
- Dim As Double fTheta, fRadius, fMidX, fMidY, f
- fMidX = iW / 2
- fMidY = iH / 2
- For iY = 0 To iH - 1
- iOffset = iY * iW
- iTrueY = iY - fMidY 'translate to center y
- For iX = 0 To iW - 1
- iTrueX = iX - fMidX 'translate to center x
- fTheta = Atan2(iTrueY, iTrueX)
- fRadius = Sqr(iTrueX * iTrueX + iTrueY * iTrueY)
- f = fTheta + fDegree * fRad * fRadius
- iNewX = fMidX + (fRadius * Cos(f))
- iNewY = fMidY + (fRadius * Sin(f))
- If (iNewY >= 0 And iNewY < iH) And (iNewX >= 0 And iNewX < iW) Then
- Cast(ULong Ptr, tBitmapData_Swirl.Scan0)[iOffset + iX] = Cast(ULong Ptr, tBitmapData.Scan0)[iNewY * iW + iNewX]
- EndIf
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Swirl, @tBitmapData_Swirl)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Swirl, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Swirl)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Swirl
- End Function
- Function _GDIPlus_BitmapApplyFilter_XRay(ByVal hImage As Any Ptr, iBias As Byte, bInvert As BOOL, bGDI As BOOL) As Any Ptr Export 'based on original code by Dewald Esterhuizen (DifferenceOfGaussians) '...'
- Dim As Any Ptr hBitmap_XRay, hBitmap_Gaussian3x3, hBitmap_Gaussian5x5, hBitmap_Greyscale, hGDIBitmap
- hBitmap_Greyscale = _GDIPlus_BitmapCreateGreyscale(hImage)
- hBitmap_Gaussian3x3 = _GDIPlus_BitmapApplyFilter_Convolution(hBitmap_Greyscale, 1, 0, 31, 0, 0, 0)
- hBitmap_Gaussian5x5 = _GDIPlus_BitmapApplyFilter_Convolution(hBitmap_Greyscale, 1, 0, 28, 0, 0, 0)
- hBitmap_XRay = _GDIPlus_BitmapCreateSubtract(hBitmap_Gaussian3x3, hBitmap_Gaussian5x5, iBias, bInvert)
- GdipDisposeImage(hBitmap_Greyscale)
- GdipDisposeImage(hBitmap_Gaussian3x3)
- GdipDisposeImage(hBitmap_Gaussian5x5)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_XRay, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_XRay)
- Return hGDIBitmap
- EndIf
- Return hBitmap_XRay
- End Function
- Function _GDIPlus_BitmapApplyFilter_DistortionBlur(ByVal hImage As Any Ptr, iDistortFactor As UShort, bGDI As BOOL) As Any Ptr Export 'based on original code by Dewald Esterhuizen '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_Distortion, hBitmap_Blur, hGDIBitmap
- Dim As Integer iStatus
- Dim As BitmapData tBitmapData, tBitmapData_Distortion
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Distortion)
- GdipBitmapLockBits(hBitmap_Distortion, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Distortion)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- GdipBitmapUnlockBits(hBitmap_Distortion, @tBitmapData_Distortion)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- Dim As Integer iX, iY, iOffset, filterX, filterY, factorMax
- iDistortFactor = IIf(iDistortFactor < 2, 2, iDistortFactor)
- factorMax = (iDistortFactor + 1) * 2
- For iY = 0 To iH - 1
- iOffset = iY * iW
- For iX = 0 To iW - 1
- filterX = Int(iX + iDistortFactor - Rnd * factorMax) Mod iW
- filterY = Int(iY + iDistortFactor - Rnd * factorMax) Mod iH
- If filterX < 0 Then filterX = 0
- If filterY < 0 Then filterY = 0
- Cast(ULong Ptr, tBitmapData_Distortion.Scan0)[iOffset + iX] = Cast(ULong Ptr, tBitmapData.Scan0)[filterY * iW + filterX]
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Distortion, @tBitmapData_Distortion)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- hBitmap_Blur = _GDIPlus_BitmapApplyFilter_Convolution(hBitmap_Distortion, 1, 0, 17, 0, 0, 0)
- GdipDisposeImage(hBitmap_Distortion)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Blur, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Blur)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Blur
- End Function
- Function _GDIPlus_BitmapApplyFilter_GridBlur(ByVal hImage As Any Ptr, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Any Ptr hBitmap_GridBlur, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_GridBlur
- Dim As Long iX, iY, iRowOffset, r, g, b, iColor
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As RECT tRect_GridBlur = Type(0, 0, iW - 1, iH - 1), tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_GridBlur)
- GdipBitmapLockBits(hBitmap_GridBlur, Cast(Any Ptr, @tRect_GridBlur), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_GridBlur)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- Dim As UInteger rax(0 To iW), gax(0 To iW), bax(0 To iW), ray(0 To iH), gay(0 To iH), bay(0 To iH), iPixels = iW + iH
- For iX = 0 To iW - 1
- r = 0
- g = 0
- b = 0
- For iY = 0 To iH - 1
- iColor = Cast(ULong Ptr, tBitmapData.Scan0)[iY * iW + iX]
- b += (iColor Shr 16) And &hFF
- g += (iColor Shr 8) And &hFF
- r += iColor And &hFF
- Next
- rax(iX) = r
- gax(iX) = g
- bax(iX) = b
- Next
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- r = 0
- g = 0
- b = 0
- For iX = 0 To iW - 1
- iColor = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- r += (iColor Shr 16) And &hFF
- g += (iColor Shr 8) And &hFF
- b += iColor And &hFF
- Next
- ray(iY) = r
- gay(iY) = g
- bay(iY) = b
- Next
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- r = Int((rax(iX) + ray(iY)) / iPixels)
- If r > 255 Then r = 255
- g = Int((gax(iX) + gay(iY)) / iPixels)
- If g > 255 Then g = 255
- b = Int((bax(iX) + bay(iY)) / iPixels)
- If b > 255 Then b = 255
- Cast(ULong Ptr, tBitmapData_GridBlur.Scan0)[iRowOffset + iX] = &hFF000000 + r Shl 16 + g Shl 8 + b
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_GridBlur, @tBitmapData_GridBlur)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_GridBlur, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_GridBlur)
- Return hGDIBitmap
- EndIf
- Return hBitmap_GridBlur
- End Function
- Function _GDIPlus_BitmapApplyFilter_BWJJNDithering(ByVal hImage As Any Ptr, fErrorMultiplier As Single, iThreshold As UByte, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As Any Ptr hBitmap_Dithered, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Dithered
- Dim As Long iX, iY, xx, yy, iRowOffset, r, g, b, e, fAvg, iARGB
- Dim As Single aError(0 To iH, 0 To iW)
- Dim As RECT tRect_Dithered = Type(0, 0, iW - 1, iH - 1), tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Dithered)
- GdipBitmapLockBits(hBitmap_Dithered, Cast(Any Ptr, @tRect_Dithered), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Dithered)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- Dim As Byte iUB, iLB1, iLB2
- iUB = UBound(matrixJJN)
- Select Case UBound(matrixJJN, 2) Mod 2
- Case 0
- iLB1 = -UBound(matrixJJN, 2) \ 2
- iLB2 = UBound(matrixJJN, 2) \ 2
- Case 1
- iLB1 = CByte(-UBound(matrixJJN, 2) / 2)
- iLB2 = CByte(UBound(matrixJJN, 2) / 2) - 1
- End Select
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- iARGB = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- r = (iARGB Shr 16) And &hFF
- g = (iARGB Shr 8) And &hFF
- b = iARGB And &hFF
- 'fAvg = (r + g + b) / 3
- fAvg = (r * 213 + g * 715 + b * 72) / 1000
- fAvg -= aError(iY, iX) * fErrorMultiplier
- e = 0
- If fAvg < iThreshold Then
- e = -fAvg
- fAvg = 0
- Else
- e = 255 - fAvg
- fAvg = 255
- EndIf
- For yy = 0 To iUB
- For xx = iLB1 To iLB2
- If (iY + yy < 0) Or (iH <= iY + yy) Or (iX + xx < 0) Or (iW <= iX + xx) Then Continue For
- aError(iY + yy, iX + xx) += e * matrixJJN(yy, xx + 2)
- Next
- Next
- Cast(ULong Ptr, tBitmapData_Dithered.Scan0)[iRowOffset + iX] = &hFF000000 + (fAvg Shl 16) + (fAvg Shl 8) + (fAvg Shl 0)
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Dithered, @tBitmapData_Dithered)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Dithered, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Dithered)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Dithered
- End Function
- Function _GDIPlus_BitmapApplyFilter_BWBayerDithering(ByVal hImage As Any Ptr, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As Any Ptr hBitmap_Dithered, hGDIBitmap
- Dim As BitmapData tBitmapData, tBitmapData_Dithered
- Dim As ULong iX, iY, iRowOffset, iColor, iR, iG, iB, iValue
- Dim As RECT tRect_Dithered = Type(0, 0, iW - 1, iH - 1), tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Dithered)
- GdipBitmapLockBits(hBitmap_Dithered, Cast(Any Ptr, @tRect_Dithered), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Dithered)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- iColor = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- iR = (iColor Shr 16) And &hFF
- iG = (iColor Shr 8) And &hFF
- iB = iColor And &hFF
- iValue = ((iR * 213 + iG * 715 + iB * 72) / 1000) Shr 2
- Cast(ULong Ptr, tBitmapData_Dithered.Scan0)[iRowOffset + iX] = IIf(iValue > matrixBayer(iX And 7, iY And 7), &hFFFFFFFF, &hFF000000)
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Dithered, @tBitmapData_Dithered)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Dithered, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Dithered)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Dithered
- End Function
- Function _GDIPlus_BitmapApplyFilter_Indexed(ByVal hImage As Any Ptr, iColors As ULong, bDither As BOOL, iDitherType As UByte, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- If iColors < 2 Then iColors = 2
- If iColors > 2 And iColors < 16 Then iColors = 16
- If iColors > 16 Then iColors = 256
- Dim As Integer iFormat = PixelFormat8bppIndexed
- Select Case iColors
- Case 2 '1 bit
- iFormat = PixelFormat1bppIndexed
- Case 16 '4 bit
- iFormat = PixelFormat4bppIndexed
- Case Else '8 bit
- iFormat = PixelFormat8bppIndexed
- End Select
- Dim As Any Ptr hBitmap_temp, hBitmap_temp2, hBitmap_Indexed, hGDIBitmap
- Dim As ULong iBytes
- Dim tPalette As tagPalette
- GdipCloneBitmapArea(0, 0, iW, iH, iFormat, hImage, @hBitmap_temp2)
- GdipGetImagePaletteSize(hBitmap_temp2, Cast(Any Ptr, @iBytes))
- GdipGetImagePalette(hBitmap_temp2, Cast(Any Ptr, @tPalette), iBytes)
- GdipCloneBitmapArea(0, 0, iW, iH, PixelFormat32bppARGB, hImage, @hBitmap_temp)
- Dim As ULong iX, iY, iRowOffset, currentPixel, NearestColor, c, iR, iG, iB
- Dim As Long errorR, errorG, errorB
- Dim As BitmapData tBitmapData, tBitmapData_Index
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Indexed)
- GdipBitmapLockBits(hBitmap_Indexed, Cast(Any Ptr, @tRect), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Index)
- GdipBitmapLockBits(hBitmap_temp, Cast(Any Ptr, @tRect), ImageLockModeRead Or ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData)
- iDitherType = IIf(iDitherType < 1, 1, IIf(iDitherType > 8, 8, iDitherType))
- Dim As ULong offsetX, offsetY, offsetIndex
- Dim As UByte iRow, iCol
- Dim As Single coefficient, matrix(Any, Any)
- Dim As UByte matrixHeight, matrixWidth, matrixStartX
- Select Case iDitherType '...'
- Case 1 'Floyd-Steinberg
- matrixHeight = 2
- matrixWidth = 3
- matrixStartX = 1
- ReDim As Single matrix(0 To matrixHeight, 0 To matrixWidth)
- CopyArray(matrixFS(), matrix())
- Case 2 'Burkes
- matrixHeight = 2
- matrixWidth = 5
- matrixStartX = 2
- ReDim As Single matrix(0 To matrixHeight, 0 To matrixWidth)
- CopyArray(matrixBurkes(), matrix())
- Case 3 'Jarvis, Judice, and Ninke
- matrixHeight = 3
- matrixWidth = 5
- matrixStartX = 2
- ReDim As Single matrix(0 To matrixHeight, 0 To matrixWidth)
- CopyArray(matrixJJN(), matrix())
- Case 4 'Stucki
- matrixHeight = 3
- matrixWidth = 5
- matrixStartX = 2
- ReDim As Single matrix(0 To matrixHeight, 0 To matrixWidth)
- CopyArray(matrixStucki(), matrix())
- Case 5 'Two-Row Sierra
- matrixHeight = 2
- matrixWidth = 5
- matrixStartX = 2
- ReDim As Single matrix(0 To matrixHeight, 0 To matrixWidth)
- CopyArray(matrixSierra2(), matrix())
- Case 6 'Three-Row Sierra
- matrixHeight = 3
- matrixWidth = 5
- matrixStartX = 2
- ReDim As Single matrix(0 To matrixHeight, 0 To matrixWidth)
- CopyArray(matrixSierra3(), matrix())
- Case 7 'Atkinson
- matrixHeight = 3
- matrixWidth = 4
- matrixStartX = 1
- ReDim As Single matrix(0 To matrixHeight, 0 To matrixWidth)
- CopyArray(matrixAtkinson(), matrix())
- Case 8 'ErrorDiffusion
- matrixHeight = 3
- matrixWidth = 5
- matrixStartX = 2
- ReDim As Single matrix(0 To matrixHeight, 0 To matrixWidth)
- CopyArray(matrixErrorDiffusion(), matrix())
- End Select
- If bDither Then
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- currentPixel = Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX]
- iR = (currentPixel Shr 16) And &hFF
- iG = (currentPixel Shr 8) And &hFF
- iB = currentPixel And &hFF
- NearestColor = IIf(iColors = 2, IIf((iR * 213 + iG * 715 + iB * 72) / 1000 > 127.5, &hFFFFFFFF, &hFF000000), FindNearestColor(currentPixel, @tPalette, iColors))
- Cast(ULong Ptr, tBitmapData_Index.Scan0)[iRowOffset + iX] = NearestColor
- errorR = iR - ((NearestColor Shr 16) And &hFF)
- errorG = iG - ((NearestColor Shr 8) And &hFF)
- errorB = iB - (NearestColor And &hFF)
- For iRow = 0 To matrixHeight - 1
- offsetY = iY + iRow
- For iCol = 0 To matrixWidth - 1
- coefficient = matrix(iRow, iCol)
- offsetX = iX + (iCol - matrixStartX)
- If (coefficient <> 0 AndAlso offsetX >= 0 AndAlso offsetX < iW AndAlso offsetY >= 0 AndAlso offsetY < iH) Then
- offsetIndex = offsetY * iW + offsetX
- c = Cast(ULong Ptr, tBitmapData.Scan0)[offsetIndex]
- Cast(ULong Ptr, tBitmapData.Scan0)[offsetIndex] = _
- PlusTruncate((c Shr 16) And &hFF, errorR * coefficient) Shl 16 Or _
- PlusTruncate((c Shr 8) And &hFF, errorG * coefficient) Shl 8 Or _
- PlusTruncate( c And &hFF, (errorB * coefficient))
- EndIf
- Next
- Next
- Next
- Next
- EndIf
- GdipBitmapUnlockBits(hBitmap_Indexed, @tBitmapData_Index)
- GdipBitmapUnlockBits(hBitmap_temp, @tBitmapData)
- GdipDisposeImage(hBitmap_temp)
- If bDither Then
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Indexed, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Indexed)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Indexed
- Else
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_temp2, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_temp2)
- Return hGDIBitmap
- EndIf
- Return hBitmap_temp2
- EndIf
- End Function
- Function FindNearestColor(iColor As ULong, ByRef tColorPalette As tagPalette Ptr, iColors As ULong) As ULong
- Dim As ULong distanceSquared, c, minDistanceSquared = 195076 '255 * 255 + 255 * 255 + 255 * 255 + 1
- Dim As UByte bestIndex = 0, Rdiff, Gdiff, Bdiff
- Dim As ULong i
- For i = 0 To iColors - 1
- c = tColorPalette -> ARGB(i)
- Rdiff = ((iColor Shr 16) And &hFF) - ((c Shr 16) And &hFF)
- Gdiff = ((iColor Shr 8) And &hFF) - ((c Shr 8) And &hFF)
- Bdiff = (iColor And &hFF) - (c And &hFF)
- distanceSquared = Rdiff * Rdiff + Gdiff * Gdiff + Bdiff * Bdiff
- If distanceSquared < minDistanceSquared Then
- minDistanceSquared = distanceSquared
- bestIndex = i
- EndIf
- Next
- 'Return IIf(tColorPalette->ARGB(bestIndex) = &hFFFFFFFF, &hFF000000, tColorPalette->ARGB(bestIndex))
- Return tColorPalette->ARGB(bestIndex)
- End Function
- Function PlusTruncate(a As UByte, b As Single) As UByte
- Return IIf(a + b < 0, 0, IIf(a + b > 255, 255, CUByte(a + b)))
- End Function
- Sub CopyArray(a() As Single, b() As Single) '...'
- Dim As UInteger x, y
- For y = 0 To UBound(a)
- For x = 0 To UBound(a, 2)
- b(y, x) = a(y, x)
- Next
- Next
- End Sub
- Function _GDIPlus_BitmapApplyFilter_Mosaic(ByVal hImage As Any Ptr, iSites As ULong, bOrdered As BOOL, bBorder As BOOL, iCalcMode As UByte, iBorderColor As ULong, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Integer iStatus
- Dim As Any Ptr hBitmap_Mosaic, hGDIBitmap
- Dim As BitmapData tBitmapData_Mosaic
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- iSites = IIf(iSites < 0, 0, IIf(iSites > (iW * iH) / 2, CULng((iW * iH) / 2), iSites))
- iSites = IIf(iSites = 0, Sqr(iW * iW + iH * iH) Shl 2, iSites)
- Dim As Single aPoints(0 To iSites, 0 To 2), d, fDist, fX, fY, fDiv, iStepX, iStepY
- Dim As Long iARGB, i, iX, iY, iRowOffset, iBorderX = CULng(iW * 0.015), iBorderY = CULng(iH * 0.015)
- Dim As RECT tRect_Mosaic = Type(0, 0, iW - 1, iH - 1)
- Randomize()
- If bOrdered Then
- fDiv = Sqr(iSites)
- iStepX = (iW / fDiv) + 1
- iStepY = (iH / fDiv) + 1
- i = 0
- For iY = 0 To CULng(fDiv + 1)
- For iX = 0 To CULng(fDiv + 1)
- aPoints(i, 0) = ((0 + iX) * iStepX) + Rnd * 4 - 2
- If aPoints(i, 0) < 0 Then aPoints(i, 0) = 0
- If aPoints(i, 0) > iW Then aPoints(i, 0) = iW -2
- aPoints(i, 1) = ((0 + iY) * iStepY) + Rnd * 4 - 2
- If aPoints(i, 1) < 0 Then aPoints(i, 1) = 0
- If aPoints(i, 1) > iH Then aPoints(i, 1) = iH - 2
- GdipBitmapGetPixel(hImage, aPoints(i, 0), aPoints(i, 1), Cast(Any Ptr, @iARGB))
- aPoints(i, 2) = iARGB
- i += 1
- If i > iSites Then Exit For, For
- Next
- Next
- Else
- For i = 0 To iSites
- aPoints(i, 0) = iBorderX + Rnd * (iW - 2 * iBorderX)
- aPoints(i, 1) = iBorderY + Rnd * (iH - 2 * iBorderY)
- GdipBitmapGetPixel(hImage, aPoints(i, 0), aPoints(i, 1), Cast(Any Ptr, @iARGB))
- aPoints(i, 2) = iARGB
- Next
- EndIf
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Mosaic)
- GdipBitmapLockBits(hBitmap_Mosaic, Cast(Any Ptr, @tRect_Mosaic), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Mosaic)
- iCalcMode = IIf(iCalcMode < 0, 0, IIf(iCalcMode > 2, 2, iCalcMode))
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- fDist = 10000.0
- For i = 0 To iSites
- fX = aPoints(i, 0) - iX
- fY = aPoints(i, 1) - iY
- Select Case iCalcMode
- Case 0 'Euclidean distance
- d = Sqr(fX * fX + fY * fY)
- Case 1 'Manhattan distance
- d = Abs(fX) + Abs(fY)
- Case 2 'Chebyshev distance
- d = max(Abs(fX), Abs(fY))
- End Select
- If d < fDist Then
- fDist = d
- Cast(ULong Ptr, tBitmapData_Mosaic.Scan0)[iRowOffset + iX] = aPoints(i, 2)
- EndIf
- Next
- Next
- Next
- If bBorder Then 'fast border routine withou aa
- Dim As Single a1, a2
- Dim As UByte ca
- Dim As ULong col
- ca = (iBorderColor And &hFF000000) Shr 24
- a1 = ca / 255 : a2 = 1 - a1
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 1 To iW - 1
- If Cast(ULong Ptr, tBitmapData_Mosaic.Scan0)[iRowOffset + iX - 1] <> Cast(ULong Ptr, tBitmapData_Mosaic.Scan0)[iRowOffset + iX] Then
- col = Cast(ULong Ptr, tBitmapData_Mosaic.Scan0)[iRowOffset + iX - 1]
- Cast(ULong Ptr, tBitmapData_Mosaic.Scan0)[iRowOffset + iX - 1] = RGB(a1 * _Red(iBorderColor) + a2 * _Red(col), _
- a1 * _Green(iBorderColor) + a2 * _Green(col), _
- a1 * _Blue(iBorderColor) + a2 * _Blue(col))
- EndIf
- Next
- Next
- For iY = 1 To iH - 1
- For iX = 0 To iW - 1
- If Cast(ULong Ptr, tBitmapData_Mosaic.Scan0)[(iY - 1) * iW + iX] <> Cast(ULong Ptr, tBitmapData_Mosaic.Scan0)[iY * iW + iX] Then
- col = Cast(ULong Ptr, tBitmapData_Mosaic.Scan0)[(iY - 1) * iW + iX]
- Cast(ULong Ptr, tBitmapData_Mosaic.Scan0)[(iY - 1) * iW + iX] = RGB(a1 * _Red(iBorderColor) + a2 * _Red(col), _
- a1 * _Green(iBorderColor) + a2 * _Green(col), _
- a1 * _Blue(iBorderColor) + a2 * _Blue(col))
- EndIf
- Next
- Next
- EndIf
- GdipBitmapUnlockBits(hBitmap_Mosaic, @tBitmapData_Mosaic)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Mosaic, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Mosaic)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Mosaic
- End Function
- Function _GDIPlus_BitmapApplyFilter_Blur(ByVal hImage As Any Ptr, iRadius As UByte) As Any Ptr Export '...'
- If iRadius < 1 Then Return 0
- Dim As Single iW, iH
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As Any Ptr hBitmap_Blurred
- Dim As BitmapData tBitmapData, tBitmapData_Blurred
- Dim As RECT tRect_Blurred = Type(0, 0, iW - 1, iH - 1)
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Blurred)
- GdipBitmapLockBits(hBitmap_Blurred, Cast(Any Ptr, @tRect_Blurred), ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData_Blurred)
- GdipBitmapLockBits(hImage, Cast(Any Ptr, @tRect_Blurred), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- Dim As UInteger iX, iY, iXX, iYY, ile, avgR, avgB, avgG, iARGB
- For iY = 0 To iH - 1
- For iX = 0 To iW - 1
- avgR = 0: avgB = 0: avgG = 0: ile = 0
- For iXX = iX To iX + iRadius
- For iYY = iY To iY + iRadius
- If (iXX >= 0 And iYY >= 0 And iXX < iW And iYY < iH) Then
- iARGB = Cast(ULong Ptr, tBitmapData.Scan0)[iYY * iW + iXX]
- avgR += (iARGB Shr 16) And &hFF
- avgG += (iARGB Shr 8) And &hFF
- avgB += iARGB And &hFF
- ile += 1
- EndIf
- Next
- Next
- Cast(ULong Ptr, tBitmapData_Blurred.Scan0)[iY * iW + iX] = &hFF000000 + (avgR \ ile) Shl 16 + (avgG \ ile) Shl 8 + (avgB \ ile)
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Blurred, @tBitmapData_Blurred)
- GdipBitmapUnlockBits(hImage, @tBitmapData)
- Return hBitmap_Blurred
- End Function
- 'Function _GDIPlus_BitmapApplyFilter_WaterDropGlassPane(ByVal hImage As Any Ptr, iPosX As UShort, iPosY As UShort, iAmount As UShort, iSizeMin As UByte, iSizeMax As UShort, iBlur As UByte, bGDI As Bool) As Any Ptr Export
- ' Dim As Single iW, iH
- ' Dim As Integer iStatus
- '
- ' iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- ' If iStatus <> 0 Then Return 0
- '
- ' Dim As Any Ptr hBitmap_WaterDrop, hBitmap_Flipped, hGDIBitmap, hGfx
- ' GdipCloneBitmapArea(0, 0, iW, iH, PixelFormat32bppARGB, hImage, @hBitmap_Flipped)
- ' GdipImageRotateFlip(hBitmap_Flipped, 6)
- ' hBitmap_WaterDrop = _GDIPlus_BitmapApplyFilter_Blur(hImage, iBlur)
- ' GdipGetImageGraphicsContext(hBitmap_WaterDrop, @hGfx)
- ' GdipDisposeImage(hBitmap_Flipped)
- ' GdipDeleteGraphics(hGfx)
- ' If bGDI Then
- ' GdipCreateHBITMAPFromBitmap(hBitmap_WaterDrop, @hGDIBitmap, &hFF000000)
- ' GdipDisposeImage(hBitmap_WaterDrop)
- ' Return hGDIBitmap
- ' EndIf
- ' Return hBitmap_WaterDrop
- 'End Function
- Private Sub drawTriangles(hImageSource As Any Ptr, hImageDestination As Any Ptr, v() As DTVertex, t() As DTTriangle, tcount As Long, bShowEdges As BOOL = False, iAlpha As UByte = &h60, bWireframe As BOOL = False) '...'
- Dim As Any Ptr hGfx, hBrush, hPen
- GdipGetImageGraphicsContext(hImageDestination, @hGfx)
- GdipSetPixelOffsetMode(hGfx, 4)
- 'If bShowEdge Then GdipSetSmoothingMode(hGfx, 4)
- GdipCreateSolidFill(&hFFFF0000, @hBrush)
- GdipCreatePen1(0, 1, 2, @hPen)
- Dim As ULong c1, c2, c3
- Dim As GpPointF aPoints(2)
- For i As Integer = 0 To tcount - 1
- Var p0 = v(t(i).v1), p1 = v(t(i).v2), p2 = v(t(i).v3)
- 'Average color of the 3 vertices
- 'GdipBitmapGetPixel(hImageSource, p0.x, p0.y, @c1)
- 'GdipBitmapGetPixel(hImageSource, p1.x, p1.y, @c2)
- 'GdipBitmapGetPixel(hImageSource, p2.x, p2.y, @c3)
- 'GdipSetSolidFillColor(hBrush, Rgba((_Red(c1) + _Red(c2) + _Red(c3)) / 3, _
- ' (_Green(c1) + _Green(c2) + _Green(c3)) / 3, _
- ' (_Blue(c1) + _Blue(c2) + _Blue(c3)) / 3, 255))
- 'Center color of the polygon
- GdipBitmapGetPixel(hImageSource, (p0.x + p1.x + p2.x) / 3, (p0.y + p1.y + p2.y) / 3, @c1)
- GdipSetSolidFillColor(hBrush, c1)
- aPoints(0).X = p0.x : aPoints(0).Y = p0.y
- aPoints(1).X = p1.x : aPoints(1).Y = p1.y
- aPoints(2).X = p2.x : aPoints(2).Y = p2.y
- If bWireframe = False Then
- GdipFillPolygon(hGfx, hBrush, @aPoints(0), 3, FillModeAlternate)
- Else
- bShowEdges = True
- EndIf
- If bShowEdges Then
- GdipSetPenColor(hPen, RGBA(_Red(c1) * 0.6666, _Green(c1) * 0.6666, _Blue(c1) * 0.6666, iAlpha))
- GdipDrawPolygon(hGfx, hPen, @aPoints(0), 3)
- End If
- Next
- GdipDeleteGraphics(hGfx)
- GdipDeleteBrush(hBrush)
- GdipDeletePen(hPen)
- End Sub
- Function _GDIPlus_BitmapApplyFilter_Delaunay(ByVal hImage As Any Ptr, iBlur As UByte, fSobel As Single, iBW As UByte, iSpaceX As ULong, iSpaceY As ULong, iBorderSpaceX As UByte, iBorderSpaceY As UByte, _ '...'
- bRndPoints As BOOL, iRndPoints As ULong, bShowEdges As BOOL, iAlpha As UByte, bWireframe As BOOL, bGDI As BOOL) As Any Ptr Export
- Dim As Single iW, iH
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- Dim As Any Ptr hGDIBitmap, hBitmap_Delaunay, hImage_tmp, hImage_tmp2, hImage_tmp3
- hImage_tmp = _GDIPlus_BitmapApplyFilter_Blur(hImage, iBlur)
- hImage_tmp2 = _GDIPlus_BitmapApplyFilter_Convolution(hImage_tmp, fSobel, 0, SOBEL, 0, 0, False)
- hImage_tmp3 = _GDIPlus_BitmapCreateBW(hImage_tmp2, iBW)
- hBitmap_Delaunay = _GDIPlus_BitmapApplyFilter_Rasterize(hImage_tmp3, iSpaceX, iSpaceY, &hFF000000, False)
- Dim As ULong i
- Dim As DTVertex vertices(iW * iH)
- Dim As BitmapData tBitmapData
- Dim As ULong iX, iY, sw = iW \ iBorderSpaceX, sh = iH \ iBorderSpaceY
- Dim As ULong iRowOffset, c = 0
- If bRndPoints Then
- iRndPoints = IIf(iRndPoints < 3, 3, iRndPoints)
- Dim As ULong iVertices, i, numPoints = 10, minDist = Sqr(iW * iW + iH * iH) \ (max(iW, iH) \ iRndPoints)
- Var points = Poisson.sample(iW, iH, minDist, numPoints)
- Dim v As FB.Vector
- v = *points
- For i = 0 To v.count - 1
- With *Cast(Poisson.SamplePoint Ptr, v[i])
- vertices(c).x = .x
- vertices(c).y = .y
- c += 1
- End With
- Next
- ' iVertices = Iif(iRndPoints < 3, iW * iH \ 66, iRndPoints)
- ' For i = 1 To iVertices
- ' vertices(c).x = (iW - 1) * Rnd()
- ' vertices(c).y = (iH - 1) * Rnd()
- ' c += 1
- ' Next
- Else
- Dim As RECT tRect = Type(0, 0, iW - 1, iH - 1)
- GdipBitmapLockBits(hBitmap_Delaunay, Cast(Any Ptr, @tRect), ImageLockModeRead, PixelFormat32bppARGB, @tBitmapData)
- For iY = 0 To iH - 1
- iRowOffset = iY * iW
- For iX = 0 To iW - 1
- If Cast(ULong Ptr, tBitmapData.Scan0)[iRowOffset + iX] <> &hFF000000 Then
- vertices(c).x = iX
- vertices(c).y = iY
- c += 1
- End If
- Next
- Next
- GdipBitmapUnlockBits(hBitmap_Delaunay, @tBitmapData)
- EndIf
- For iX = 0 To iW + 2 * sw Step sw
- If iX <= iW Then
- vertices(c).x = iX
- vertices(c).y = 0
- c += 1
- End If
- Next
- For iX = 0 To iW + 2 * sw Step sw
- If iX <= iW Then
- vertices(c).x = iX
- vertices(c).y = iH
- c += 1
- End If
- Next
- For iY = 0 To iH + 2 * sh Step sh
- If iY <= iH Then
- vertices(c).x = 0
- vertices(c).y = iY
- c += 1
- End If
- Next
- For iY = 0 To iH + 2 * sh Step sh
- If iY <= iH Then
- vertices(c).x = iW
- vertices(c).y = iY
- c += 1
- End If
- Next
- Dim As Long nv = (c - 1), ntris
- Dim As DTTriangle triangles(Any)
- triangulate(vertices(), nv, triangles(), @ntris)
- Dim As Any Ptr hGfx
- GdipGetImageGraphicsContext(hBitmap_Delaunay, @hGfx)
- GdipGraphicsClear(hGfx, &hFF000000)
- GdipDeleteGraphics(hGfx)
- drawTriangles(hImage, hBitmap_Delaunay, vertices(), triangles(), ntris, bShowEdges, iAlpha, bWireframe)
- GdipDisposeImage(hImage_tmp)
- GdipDisposeImage(hImage_tmp2)
- GdipDisposeImage(hImage_tmp3)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Delaunay, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Delaunay)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Delaunay
- End Function
- Function _GDIPlus_BitmapApplyFilter_Spiral(ByVal hImage As Any Ptr, iMode As UByte, iBgColor As ULong, bGreyScale As BOOL, bGDI As BOOL) As Any Ptr Export '...'
- Dim As Single iW, iH
- Dim As Integer iStatus
- iStatus = GdipGetImageDimension(hImage, @iW, @iH)
- If iStatus <> 0 Then Return 0
- iMode = IIf(iMode > 1 , 1, iMode)
- Dim As Single radiusSpan = 9, arcLengthStep = 2.5, rotationSpeed = fPi / 20, maxRadius = max(iW, iH) * 0.501
- Randomize
- Dim As PERLINNOISE Perlin
- Dim As Single radius, radian, x, y, drawnRad, px, py, radianStep, sw, col2, t1, t2
- Dim As ULong col, cx, cy
- cx = iW \ 2
- cy = iH \ 2
- drawnRad = 0
- radian = 0
- radius = radiusSpan / 2
- x = cx + Cos(radian) * radius
- y = cy + Sin(radian) * radius
- Dim As Any Ptr hGDIBitmap, hBitmap_Spiral, hBitmap_Greyscale, hGfx, hPen, hBrush
- GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap_Spiral)
- GdipGetImageGraphicsContext(hBitmap_Spiral, @hGfx)
- GdipSetSmoothingMode(hGfx, 4)
- GdipSetPixelOffsetMode(hGfx, PixelOffsetModeHalf)
- GdipCreatePen1(&hFF000000, 1, 2, @hPen)
- GdipCreateSolidFill(&hFF000000, @hBrush)
- GdipGraphicsClear(hGfx, iBgColor)
- If bGreyScale Then hBitmap_Greyscale = _GDIPlus_BitmapCreateGreyscale(hImage)
- Do
- px = x
- py = y
- radianStep = Map(arcLengthStep, 0, radius * f2Pi, 0, f2Pi)
- radian += radianStep
- radius += Map(radianStep, 0, f2Pi, 0, radiusSpan)
- x = cx + Cos(radian) * radius
- y = cy + Sin(radian) * radius
- If bGreyScale Then
- GdipBitmapGetPixel(hBitmap_Greyscale, x, y, @col)
- Else
- GdipBitmapGetPixel(hImage, x, y, @col)
- EndIf
- col2 = Map((_Red(col) + _Green(col) + _Blue(col)) / 3, 0, 255, 1, 0)
- col2 = col2 * col2 * col2
- sw = Map(col2, 1, 0, radiusSpan * 0.7, 0.01)
- sw += (Perlin.Noise2D(x, y) - 0.5) * radiusSpan * 0.2
- Select Case iMode
- Case 0
- GdipSetPenWidth(hPen, sw)
- GdipSetPenColor(hPen, col - &h10000000)
- GdipDrawLine(hGfx, hPen, px, py, x, y)
- Case 1
- GdipSetSolidFillColor(hBrush, col - &h10000000)
- t1 = sw / 2
- t2 = sw * 1.5
- GdipFillEllipse(hGfx, hBrush, x - t1, y - t1, t2, t2)
- End Select
- drawnRad += radianStep
- Loop Until radius > maxRadius
- If bGreyScale Then GdipDisposeImage(hBitmap_Greyscale)
- GdipDeletePen(hPen)
- GdipDeleteBrush(hBrush)
- GdipDeleteGraphics(hGfx)
- If bGDI Then
- GdipCreateHBITMAPFromBitmap(hBitmap_Spiral, @hGDIBitmap, &hFF000000)
- GdipDisposeImage(hBitmap_Spiral)
- Return hGDIBitmap
- EndIf
- Return hBitmap_Spiral
- End Function
- End Extern
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement