Hallo,
ich arbeite aktuell an einem kleinen Programm, das unter anderem einen (Gaussian) Blur Effect implementieren soll. diylab hatte mir hierfür (s)einen Code bereitgestellt.
Der Aufruf erfolgt so:
Nun ist da der zweite Parameter von der
Es handelt sich um Zeile 74:
Ist der Wert kleiner (etwas wie 1), dann fliegt eine
Ich habe mal Haltepunkte gesetzt und durchdebuggt, aber ich konnte nicht darauf schließen, wo das Problem ist, zumal der Code ziemlich unüberschaubar ist.
Bei @diylab mag der Compiler jetzt auch nicht mehr, sodass er's auch nicht debuggt kriegt. Es soll allerdings vorher funktioniert haben.
Natürlich könnte man hier WPF verwenden, was wesentlich einfacher und performanter wäre. Es ist aber ein Kundenwunsch, das mit Windows Forms zu machen.
Der Code ansonsten funktioniert. Wenn ich als Wert 0 eintrage, dann fliegt keine Exception und das Bild in der PictureBox ist halt unsichtbar/weiß.
Hat jemand eine Idee, was das Problem ist bzw. alternative Funktionen, die mit
Grüße
ich arbeite aktuell an einem kleinen Programm, das unter anderem einen (Gaussian) Blur Effect implementieren soll. diylab hatte mir hierfür (s)einen Code bereitgestellt.
VB.NET-Quellcode
- ''' <summary>
- ''' Erstellt einen Blureffekt.
- ''' </summary>
- Private Function StackBlur(ByVal SourceImage As Bitmap, ByVal radius As Integer) As Bitmap
- If radius < 1 Then Return Nothing
- Using OrgBmp As New Bitmap(SourceImage)
- Dim rct = New Rectangle(0, 0, OrgBmp.Width, OrgBmp.Height)
- Dim dest = New Integer(rct.Width * rct.Height - 1) {}
- Dim source = New Integer(rct.Width * rct.Height - 1) {}
- Dim bits = OrgBmp.LockBits(rct, ImageLockMode.ReadWrite, OrgBmp.PixelFormat)
- Marshal.Copy(bits.Scan0, source, 0, source.Length)
- OrgBmp.UnlockBits(bits)
- Dim w As Integer = rct.Width
- Dim h As Integer = rct.Height
- Dim wm As Integer = w - 1
- Dim hm As Integer = h - 1
- Dim wh As Integer = w * h
- Dim div As Integer = radius + radius + 1
- Dim r = New Integer(wh - 1) {}
- Dim g = New Integer(wh - 1) {}
- Dim b = New Integer(wh - 1) {}
- Dim rsum As Integer, gsum As Integer, bsum As Integer, x As Integer, y As Integer, i As Integer, p1 As Integer, p2 As Integer, yi As Integer
- Dim vmin = New Integer(Max(w, h) - 1) {}
- Dim vmax = New Integer(Max(w, h) - 1) {}
- Dim dv = New Integer(256 * div - 1) {}
- For i = 0 To 256 * div - 1
- dv(i) = (i \ div)
- Next
- Dim yw As Integer = InlineAssignHelper(yi, 0)
- For y = 0 To h - 1
- rsum = InlineAssignHelper(gsum, InlineAssignHelper(bsum, 0))
- For i = -radius To radius
- Dim p As Integer = source(yi + Min(wm, Max(i, 0)))
- rsum += (p And &HFF0000) >> 16
- gsum += (p And &HFF00) >> 8
- bsum += p And &HFF
- Next
- For x = 0 To w - 1
- r(yi) = dv(rsum)
- g(yi) = dv(gsum)
- b(yi) = dv(bsum)
- If y = 0 Then
- vmin(x) = Min(x + radius + 1, wm)
- vmax(x) = Max(x - radius, 0)
- End If
- p1 = source(yw + vmin(x))
- p2 = source(yw + vmax(x))
- rsum += ((p1 And &HFF0000) - (p2 And &HFF0000)) >> 16
- gsum += ((p1 And &HFF00) - (p2 And &HFF00)) >> 8
- bsum += (p1 And &HFF) - (p2 And &HFF)
- yi += 1
- Next
- yw += w
- Next
- For x = 0 To w - 1
- rsum = InlineAssignHelper(gsum, InlineAssignHelper(bsum, 0))
- Dim yp As Integer = -radius * w
- For i = -radius To radius
- yi = Max(0, yp) + x
- rsum += r(yi)
- gsum += g(yi)
- bsum += b(yi)
- yp += w
- Next
- yi = x
- For y = 0 To h - 1
- dest(yi) = CInt(&HFF000000UI Or CUInt(dv(rsum) << 16) Or CUInt(dv(gsum) << 8) Or CUInt(dv(bsum)))
- If x = 0 Then
- vmin(y) = Min(y + radius + 1, hm) * w
- vmax(y) = Max(y - radius, 0) * w
- End If
- p1 = x + vmin(y)
- p2 = x + vmax(y)
- rsum += r(p1) - r(p2)
- gsum += g(p1) - g(p2)
- bsum += b(p1) - b(p2)
- yi += w
- Next
- Next
- Dim bits2 = OrgBmp.LockBits(rct, ImageLockMode.ReadWrite, OrgBmp.PixelFormat)
- Marshal.Copy(dest, 0, bits2.Scan0, dest.Length)
- OrgBmp.UnlockBits(bits)
- bits = Nothing
- Return New Bitmap(OrgBmp)
- End Using
- End Function
- Private Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
- target = value
- Return value
- End Function
Der Aufruf erfolgt so:
Nun ist da der zweite Parameter von der
StackBlur
-Funktion für den Radius. Werte zwischen 100-1000 lösen bei diesem eine IndexOutOfRangeException
aus: Der Index war außerhalb des Arraybereichs.
Es handelt sich um Zeile 74:
rsum += r(yi)
Ist der Wert kleiner (etwas wie 1), dann fliegt eine
OverflowException
: Die arithmetische Operation hat einen Überlauf verursacht.
Ich habe mal Haltepunkte gesetzt und durchdebuggt, aber ich konnte nicht darauf schließen, wo das Problem ist, zumal der Code ziemlich unüberschaubar ist.
Bei @diylab mag der Compiler jetzt auch nicht mehr, sodass er's auch nicht debuggt kriegt. Es soll allerdings vorher funktioniert haben.
Natürlich könnte man hier WPF verwenden, was wesentlich einfacher und performanter wäre. Es ist aber ein Kundenwunsch, das mit Windows Forms zu machen.
Der Code ansonsten funktioniert. Wenn ich als Wert 0 eintrage, dann fliegt keine Exception und das Bild in der PictureBox ist halt unsichtbar/weiß.
Hat jemand eine Idee, was das Problem ist bzw. alternative Funktionen, die mit
LockBits
, Matrizen oder was weiß ich arbeiten? Habe mit Grafiksachen nicht so viel zu tun.^^Grüße
#define for for(int z=0;z<2;++z)for // Have fun!
Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose!
Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da
Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose!
Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Trade“ ()