motion detection - xxdarklord65xx - May 27, 2017
hello people .
i got a class for motion detection what it really do is that
it compare between the two images and send the changed part or the detected motion .
my problem is that when it send the changed image how can i in the server handle it or deal with it . i got no idea at all .
Code Imports System.Drawing.Imaging
Imports System.IO
Imports System.Runtime.InteropServices
Public Class MotionDetection
Public lastBitmap As Bitmap
Public decodeBitmap As Bitmap
Public bitmapWidth As Integer
Public bitmapHeight As Integer
Public Sub Encode(bmp As Bitmap, outStream As Stream, quality As Integer)
On Error Resume Next
If lastBitmap Is Nothing Then
lastBitmap = bmp
bitmapWidth = bmp.Width
bitmapHeight = bmp.Height
outStream.Write(BitConverter.GetBytes(bitmapWidth), 0, 4)
outStream.Write(BitConverter.GetBytes(bitmapHeight), 0, 4)
Dim bitmapData As Byte() = ConvertToJpeg(bmp, quality)
outStream.Write(BitConverter.GetBytes(bitmapData.Length), 0, 4)
outStream.Write(bitmapData, 0, bitmapData.Length)
Return
End If
Dim bmpData As BitmapData = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat)
Dim lastBmpData As BitmapData = lastBitmap.LockBits(New Rectangle(0, 0, lastBitmap.Width, lastBitmap.Height), ImageLockMode.ReadWrite, bmp.PixelFormat)
Dim Stride As Integer = Math.Abs(bmpData.Stride)
Dim PixelSize As Integer = Stride / bmp.Width
Dim RectHeightChanges As New List(Of Rectangle)()
For i As Integer = 0 To bmp.Height - 1
Dim Offset As Integer = i * Stride
Dim src As New IntPtr(bmpData.Scan0.ToInt32() + Offset)
Dim dest As New IntPtr(lastBmpData.Scan0.ToInt32() + Offset)
If memcmp(src, dest, Stride) <> 0 Then
If RectHeightChanges.Count > 0 Then
Dim rect As Rectangle = RectHeightChanges(RectHeightChanges.Count - 1)
If rect.Y + rect.Height = i Then
RectHeightChanges(RectHeightChanges.Count - 1) = New Rectangle(0, rect.Y, bmp.Width, rect.Height + 1)
Else
RectHeightChanges.Add(New Rectangle(0, i, bmp.Width, 1))
End If
Else
RectHeightChanges.Add(New Rectangle(0, i, bmp.Width, 1))
End If
End If
Next
Dim LastChanges As New List(Of Rectangle)()
For Each rect As Rectangle In RectHeightChanges
For x As Integer = 0 To rect.Width - 1 Step 50
Dim width As Integer
Dim height As Integer
If x + 50 > rect.Width Then
width = rect.Width - x
Else
width = 50
End If
If rect.Y + rect.Height >= bmp.Height Then
height = bmp.Height - rect.Height
Else
height = rect.Height
End If
For y As Integer = rect.Y To (rect.Y + rect.Height) - 1
Dim Offset As Integer = (y * Stride) + (x * PixelSize)
Dim src As New IntPtr(bmpData.Scan0.ToInt32() + Offset)
Dim dest As New IntPtr(lastBmpData.Scan0.ToInt32() + Offset)
If memcmp(src, dest, width * PixelSize) <> 0 Then
LastChanges.Add(New Rectangle(x, rect.Y, width, rect.Height))
Exit For
End If
Next
Next
Next
bmp.UnlockBits(bmpData)
lastBitmap.UnlockBits(lastBmpData)
For Each rect As Rectangle In LastChanges
outStream.Write(BitConverter.GetBytes(rect.X), 0, 4)
outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4)
bmpData = bmp.LockBits(New Rectangle(rect.X, rect.Y, rect.Width, rect.Height), ImageLockMode.[ReadOnly], bmp.PixelFormat)
Using newBitmap As New Bitmap(rect.Width, rect.Height, bmpData.Stride, bmp.PixelFormat, bmpData.Scan0)
Dim data As Byte() = ConvertToJpeg(newBitmap, quality)
outStream.Write(BitConverter.GetBytes(data.Length), 0, 4)
outStream.Write(data, 0, data.Length)
End Using
bmp.UnlockBits(bmpData)
Next
lastBitmap.Dispose()
lastBitmap = bmp
End Sub
<DllImport("msvcrt.dll", CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function memcmp(Dest As IntPtr, Src As IntPtr, Length As Integer) As Integer
End Function
Private Function ConvertToJpeg(img As Bitmap, q As Integer) As Byte()
On Error Resume Next
Const ParamAmount As Integer = 1
Dim qualityParam As New EncoderParameter(Imaging.Encoder.Quality, q)
Dim jpegCodec As ImageCodecInfo = GetEncoderInfo("image/jpeg")
Dim encoderParams As New EncoderParameters(ParamAmount)
encoderParams.Param(0) = qualityParam
Dim ms As New MemoryStream()
img.Save(ms, jpegCodec, encoderParams)
Return ms.GetBuffer()
End Function
Private Function GetEncoderInfo(mimeType As String) As ImageCodecInfo
On Error Resume Next
Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
For i As Integer = 0 To codecs.Length - 1
If (codecs(i).MimeType = mimeType) Then
Return codecs(i)
End If
Next
Return Nothing
End Function
End Class
* - Ninja - May 27, 2017
Like Orka said, just create an event for it that the user can subscribe to.
* - xxdarklord65xx - May 27, 2017
(May 27, 2017 07:54 AM)Orka Wrote: Create a delegate and event handler where the user can subscribe. You could also implement your own EventArgs and carry the image change differential, just a thought.
okai lets say we raise an event when the changed image is received .
how can i carry the changed image with the real one ? because the changed image will be the small part in the real one . so how can i merge them together
* - xxdarklord65xx - May 27, 2017
(May 27, 2017 10:08 AM)Orka Wrote: See the latter part of my response. Implement a class deriving from EventArgs and set some properties of your own, passing that as part of your handler.
true . but i dont see it as the right way to decode the image . if u saw the function it write in the outstream the changed image
Code Dim data As Byte() = ConvertToJpeg(newBitmap, quality)
newimage = data
outStream.Write(BitConverter.GetBytes(data.Length), 0, 4)
outStream.Write(data, 0, data.Length)
when i receive it . i must decode it . and i dont know how decode it . thats my problem exactly
* - xxdarklord65xx - May 27, 2017
(May 27, 2017 11:21 AM)Orka Wrote: Ah, this is code from imminent monitor's server. Its usage can be found in the client code.
yeah thats the problem . i just wanna know how to do it . aint using it for bad stuff .
|