How to update a large (over 4 million item) List(Of Byte) quickly by altering indexes contained in a Dictionary(Of Integer, Byte) where the Dictionaries keys are the indexes in the List(Of Byte) that need to be changed to the values for those indexes?
I'm having some difficulty with transferring images from a UDP Client to a UDP Server. The issue is receiving the bytes necessary to update an original image sent from the Client to the Server and updating the Servers List(Of Byte) with the
new bytes replacing bytes in that list. This is a simplex connection where the Sever receives and the Client sends to utilize the least amount of bandwidth for a "Remote Desktop" style application where the Server side needs image updates of whatever
occurs on the Client desktop.
So far I can tranfer images with no issue. The images can be be any image type (.Bmp, .Gif, .JPeg, .Png, etc). I was working with sending .JPeg's as they appear to be the smallest size image when a Bitmap is saved to a memory stream as type
.JPeg. And then I am using GZip to compress that byte array again so it is much smaller. However on a loopback on my NIC the speed for sending a full size screen capture is not very fast as the Server updates fairly slowly unless the Clients screen capture
Bitmap is reduced in size to about 1/3'd of the original size. Then about 12000 bytes or less are sent for each update.
Due to .JPeg compression I suppose there is no way to get the difference in bytes between two .JPegs and only send those when something occurs on the desktop that alters the desktop screen capture image. Therefore I went to using .Bmp's as each
.Bmp contains the same number of bytes in its array regardless of the image alterations on the desktop. So I suppose the difference in bytes from a second screen capture and an inital screen capture are what is different in the second image from the initial
image.
What I have done so far is save an initial Bitmap of a screen capture using a memory stream and saving as type .Bmp which takes less than 93 milliseconds for 4196406 bytes. Compressing that takes less than 118 milliseconds to 197325 bytes for
the current windows on the desktop. When that is done PictureBox1 is updated from nothing to the captured image as the PictureBox's background image with image layout zoom and the PictureBox sized at 1/2 my screens width and 1/2 my screens height.
Then I save a new Bitmap the same way which now contains different image information as the PictureBox is now displaying an image so its back color is no longer displayed (solid color Aqua) and the cursor has moved to a different location. The
second Bitmap is also 4196406 in bytes and compressed it was 315473 bytes in size.
I also just found code from this link Converting a Bitmap to a Byte Array (and Byte Array to Bitmap) which gets a byte array
directly from a Bitmap and the size of that is 3148800 for whatever is full screen captured on my laptop. So I should be able to work with smaller byte arrays at some point.
The issue I'm having is that once the Client sends an image of the desktop to the Server I only want to update the server with any differences occuring on the Clients desktop. So what I have done is compare the first screen captures bytes (stored
in a List(Of Byte)) to the second screen captures bytes (stored in a List(Of Byte)) by using a For/Next for 0 to 4196405 where if a byte in the first screen captures List is not equal to a byte in the second screen captures List I add the index and byte of
the second screen captures list to a Dictionary(Of Integer, Byte). The Dictionary then only contains the indexes and bytes that are different between the first screen capture and second screen capture. This takes about 125 milliseconds which I think is pretty
fast for 4196406 byte comparison using a For/Next and adding all the different bytes and indexes for each byte to a Dictionary.
The difference in Bytes between the inital screen capture and the second screen capture is 242587 as an example which changes of course. For that amount of bytes the Dictionary contains 242587 integers as indexes and 242587 bytes as different
bytes totaling 485174 bytes for both arrays (keys, values). Compressed the indexes go from 242587 to 43489 bytes and the values go from 242587 to 34982 bytes. Which means I will have to send 78, 481 bytes from the Client to the Server to update the display
on the server. Quite smaller than the original 4196406 bytes of the second Bitmap saved to type .Bmp or the compressed size of that array which was 315473 bytes. Plus a few bytes I add as overhead so the server knows when an image array ends and how many packets
were sent for the array so it can discard complete arrays if necessary since UDP is lossfull although probably not so much in current networks like it may originally have been when the internet started.
In reality the data from the Client to the Server will mostly be the cursor as it moves and updating the Server image with only a few hundred bytes I would imagine at a time. Or when the cursor selects a Button for example and the Buttons
color changes causing those differences in the original screen capture.
But the problem is if I send the Dictionaries Indexes and Bytes to the Server then I need to update the original Bitmap List(Of Byte) on the server by removing the Bytes in the received informations Index locations array from the Servers Bitmap
List(Of Byte) and replacing those Bytes with the Bytes in the received informations Byte array. This takes so long using a For/Next for however many indexes are in the received informations Index array to update the Bitmap List(Of Byte) on the server using
"Bmp1Bytes.RemoveAt(Index As Integer)" followed by "Bmp1Bytes.Insert(Index As Integer, Item As Byte)" in the For/Next.
I've tried various For/Next statements including using a new List(Of Byte) with If statements so If the the integer for the For/Next ='s the Key in a Dictionary(Of Integer, Byte) using a Counter to provide the Dictionaries Key value then
the Dictionaries byte value will be added to the List(Of Byte) and the counter will increas by one Else the List(Of Byte) adds the original "Bmp1Bytes" byte at that index to the new List(Of Byte). This takes forever also.
I also tried the same For/Next adding to a new Dictionary(Of Integer, Byte) but that takes forever too.
I think I could use RemoveRange and AddRange to speed things up. But I don't know how to retrieve a contiguous range of indexes in the received indexes that need to be updated in the servers "Bmp1Bytes" List(Of Byte) from the received
array of indexes and bytes which are in a Dictionary(Of Integer, Byte). But I believe this would even be slower than some realistic method for replacing all Bytes in a List(Of Byte) when I have the indexes that need to be replaced and the bytes to replace
them with.
Even if I just used AddRange on a new List(Of Byte) to add ranges of bytes from the original "Bmp1Bytes" and the changes from the Dictionary(Of Integer, Byte) I think this would be rather slow. Although I don't know how to do that
by getting contiguous ranges of indexes from the Dictionaries keys.
So I was wondering if there is some method perhaps using Linq or IEnumerable which I've been unable to figure anything out which could do this.
I do have some copy and pasted code which I don't understand how it works that I am using which I would guess could be altered for doing something like this but I can't find information that provides how the code works. Or even if I did
maybe I can't understand it. Like the code below which is extremely fast.
Dim strArray() As String = Array.ConvertAll(Of Integer, String)(BmpComparisonDict.Keys.ToArray, Function(x) x.ToString())
La vida loca
Monkeyboy,
That was quite a bit to read, but still a bit unclear. Could you put a specific list of goals/questions, asked in the smallest possible form?
It seems like either you're making a program that monitors activity on your computer, or you're writing some kind of remote pc app.
When you do get your bytes from using lockbits, keep in mind all the files header info would be lost. I think retaining the header info is worth the extra bytes.
The other, thing: I'm not sure if you're taking 32bpp screen shots, but also keep in mind that the "whole desktop" is the final destination for blended graphics, if that makes sense. What I mean is that there is no need to capture an "alpha"
channel for a desktop screenshot, as alpha would always be 255, this could save you 1 byte per pixel captured... Theres nothing "behind" the desktop, therefore no alpha, and every window shown above the desktop is already blended. I suggest using
24Bpp for a full screen capture.
Your X,Y information for the mouse could be stored as UINT16, this would save you a measly 2 bytes per location update/save.
When you update your byte arrays, maybe you can turn the array into a stream and write to whatever index, however many bytes, that should prevent a "Shift" of bytes, and instead overwrite any bytes that "get in the way".
ex
Dim example As String = "This is an example."
Dim insertString As String = "was"
Dim insertBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(insertString)
Dim bytes As Byte() = System.Text.Encoding.ASCII.GetBytes(example)
Dim modifiedBytes As Byte() = {}
Using ms As New System.IO.MemoryStream(bytes)
ms.Position = 5
ms.Write(insertBytes, 0, 3)
modifiedBytes = ms.ToArray
End Using
Dim newString As String = System.Text.Encoding.ASCII.GetString(modifiedBytes)
'Notice how below there isn't the word "is" anymore, and that there isn't a
'space.
'This demonstrates that you overwrite existing data, versus shifting everything to
'the right.
'Returns: This wasan example.
MsgBox(newString)
“If you want something you've never had, you need to do something you've never done.”
Don't forget to mark
helpful posts and answers
! Answer an interesting question? Write a
new article
about it! My Articles
*This post does not reflect the opinion of Microsoft, or its employees.
Well it's too much to read. I was really tired when I wrote it. Even the below is too much to read but perhaps gets the point across of what I would like to do which I think
Joel Engineer may have answered but I'm not sure. As I'm still too tired to understand that yet and research what he said in order to figure it out yet.
But maybe the code below can provide the concept of the operation with the comments in it. But seeing as how I'm still tired it may be confused.
Option Strict On
Imports System.Windows.Forms
Imports System.IO
Imports System.IO.Compression
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Public Class Form1
Dim Bmp1Bytes As New List(Of Byte)
Dim Bmp1BytesCompressed As New List(Of Byte)
Dim Bmp2Bytes As New List(Of Byte)
Dim BmpComparisonDict As New Dictionary(Of Integer, Byte)
Dim BmpDifferenceIndexesCompressed As New List(Of Byte)
Dim BmpDifferenceBytesCompressed As New List(Of Byte)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
SomeSub()
End Sub
Private Sub SomeSub()
' Pretend this code is in UDP Client app. A screen capture is performed of the desktop. Takes about 90 milliseconds.
Bmp1Bytes.Clear()
Using BMP1 As New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)
Using g1 As Graphics = Graphics.FromImage(BMP1)
g1.CopyFromScreen(0, 0, 0, 0, BMP1.Size)
Cursor.Draw(g1, New Rectangle(Cursor.Position.X, Cursor.Position.Y, Cursor.Size.Width, Cursor.Size.Height))
Using MS As New MemoryStream
BMP1.Save(MS, System.Drawing.Imaging.ImageFormat.Bmp)
Bmp1Bytes.AddRange(MS.ToArray)
End Using
End Using
End Using
Bmp1BytesCompressed.AddRange(Compress(Bmp1Bytes.ToArray))
' UDP Client app sends Bmp1BytesCompressed.ToArray to UDP Server which is the entire image of the desktop that the UDP
' Client is on. This image takes awhile to send since compressed it is about 177000 bytes from over 4000000 bytes.
' I will be using different code just to get the bytes from the actual Bitmap in the future. That is not important for now.
' Pretend the UDP Server has received the bytes, decompressed the array received into a List(Of Byte) and is displaying
' the image of the UDP Clients desktop in a PictureBox.
' Now the image on the UDP Clients desktop changes due to the mouse cursor moving as an example. Therefore a new Bitmap
' is created from a screen capture. This takes about 90 milliseconds.
Bmp2Bytes.Clear()
Using BMP2 As New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)
Using g1 As Graphics = Graphics.FromImage(BMP2)
g1.CopyFromScreen(0, 0, 0, 0, BMP2.Size)
Cursor.Draw(g1, New Rectangle(Cursor.Position.X, Cursor.Position.Y, Cursor.Size.Width, Cursor.Size.Height))
Using MS As New MemoryStream
BMP2.Save(MS, System.Drawing.Imaging.ImageFormat.Bmp)
Bmp2Bytes.AddRange(MS.ToArray)
End Using
End Using
End Using
' Now I have the original images bytes in Bmp1Bytes and the new images bytes in Bmp2Bytes on the UDP Client. But I don't
' want to send all of the bytes in Bmp2Bytes to the UDP Server. Just the indexes of and the bytes that are different in
' Bmp2Bytes from Bmp1Bytes.
' This takes less than 100 milliseconds for what I've tested so far where over 500000 bytes in Bmp2Bytes are different
' than the bytes in Bmp1Bytes. Usually that amount would be much less. But during testing I was displaying the image
' from Bmp1 bytes in a PictureBox so a large amount of data would change between the first screen shot, the PictureBox
' then displaying an image on the same PC and then the second screen shot.
BmpComparisonDict.Clear()
For i = 0 To Bmp1Bytes.Count - 1
If Bmp1Bytes(i) <> Bmp2Bytes(i) Then
BmpComparisonDict.Add(i, Bmp2Bytes(i))
End If
Next
' So now I have all the difference bytes and their indexes from Bmp2Bytes in the BmpComparisonDict. So I compress
' the indexes into on List and the Bytes into another List.
BmpDifferenceIndexesCompressed.Clear()
BmpDifferenceBytesCompressed.Clear()
BmpDifferenceIndexesCompressed.AddRange(Compress(BmpComparisonDict.Keys.SelectMany(Function(d) BitConverter.GetBytes(d)).ToArray()))
BmpDifferenceBytesCompressed.AddRange(Compress(BmpComparisonDict.Values.ToArray))
' Now pretend the UDP Client has sent both those arrays to the UDP Server which has added both decompressed arrays
' to a Dictionary(Of Integer, Byte). And the server has the original image decompressed bytes received in a List
' called Bmp1Bytes also.
' This is where I am stuck. The UDP Server has the Dictionary. That part was fast. However there is no
' fast method I have found for creating a new List(Of Byte) where bytes in the originally received List(Of Byte) that
' do not have to be altered are placed into a new List(Of Byte) except for the indexes listed in the
' Dictionary(Of Integer, Byte) that need to be placed into the appropriate index locations of the new List(Of Byte).
' The below example for doing so is exceptionally slow. Pretend UpdateDictionary has all of the decompressed indexes
' and bytes received by the UDP Server for the update contained within it.
Dim UpdateDictionary As New Dictionary(Of Integer, Byte)
Dim UpdatedBytes As New List(Of Byte)
Dim Counter As Integer = 0
For i = 0 To Bmp1Bytes.Count - 1
If i = UpdateDictionary.Keys(Counter) Then ' Provides the index contained in the Keys for the Dictionary
UpdatedBytes.Add(UpdateDictionary.Values(Counter))
Counter += 1
If Counter > UpdateDictionary.Count - 1 Then Counter = 0
Else
UpdatedBytes.Add(Bmp1Bytes(i))
End If
Next
' So what I'm trying to do is find an extremely fast method for performing something similar to what the
' above operation performs.
End Sub
Private Function Compress(BytesToCompress() As Byte) As List(Of Byte)
Dim BytesCompressed As New List(Of Byte)
Using compressedStream = New MemoryStream()
Using zipStream = New GZipStream(compressedStream, CompressionMode.Compress)
zipStream.Write(BytesToCompress, 0, BytesToCompress.Count)
zipStream.Close()
BytesCompressed.AddRange(compressedStream.ToArray)
End Using
End Using
Return BytesCompressed
End Function
Private Function Decompress(BytesToDecompress() As Byte) As List(Of Byte)
Dim BytesDecompressed As New List(Of Byte)
Using DecompressedStream = New MemoryStream()
Using zipStream = New GZipStream(DecompressedStream, CompressionMode.Decompress)
zipStream.Write(BytesToDecompress, 0, BytesToDecompress.Count)
zipStream.Close()
BytesDecompressed.AddRange(DecompressedStream.ToArray)
End Using
End Using
Return BytesDecompressed
End Function
End Class
La vida loca
Similar Messages
-
My phone was recently updated to 8.1. After the update, when text messages are sent when my phone is turned off, they no longer appear when I turn the phone on. Is there something in Settings that needs to be changed?
MetsFanGirl,
Thanks for verifying. Are you having issues receiving both iMessages and standard text messages when they are sent when the phone is turned off? Try this and test... http://vz.to/1qjiOs7
LindseyT_VZW
Follow us on Twitter @VZWSupport -
Hello! I'm out of the country and all my iWeb information is on my computer at home. Now I need to make changes on the webpage... how can i do that without using the computer i made the page on? Thank you!!
iWeb uses the domain.sites2 files to store its assets.
You'll find it here :
~/Library/Application Support/iWeb/
where ~ is your Home directory.
If you take a computer with you, you have to store that file in the same location.
It's not different from taking documents with you if you want to edit them.
A solution is to remotely control your computer at home.
TeamViewer, LogMeIn, Apple Remote Desktop or any VNC application you can use, like "Chicken of the VNC". -
On my Ipad, under Settings for ICloud, under ''advanced'', there is an E-mail address that needs to be changed. How do I do that ?
On my IPhone5, the address under ''advanced'' has been changed automatically to the right @icloud address.
ThanksHi jeanrobca,
Welcome to the Support Communities!
If the settings for your Apple ID have changed, you can edit and update that information by clicking on the link below:
Frequently asked questions about Apple ID
http://support.apple.com/kb/HT5622
Click on My Apple ID to access and edit your account.
Then you can sign out of your iCloud account and sign back in with the corrected information.
Apple ID: What to do after you change your Apple ID
http://support.apple.com/kb/HT5796?viewlocale=en_US&locale=en_US
Cheers,
- Judy -
I installed snow leopard which I now realise that it was the wrong one because it came out before my laptop and now it won't changed from the grey screen with the apple on it how do I fix it ???
MacBook Pro
Apple - Support - MacBook Pro
Mac OS Version builds
When did yours come out? what does the above show as model and minimum build?
You should have yoru OEM OS X DVD, not one from another Mac, or retail, though the last retail OS X DVD was a year ago 10.6.3.
If it installed, I don't see an issue unless the drive had corrupt directory etc.
What you need to do is repair your boot drive or restore from backup. -
I had an Apple ID under an old email address that I have now changed, but the old address still shows up in my iCloud account since I installed Yosemite. How do I get rid of that old account altogether?
You cannot merge accounts.
You need to sign into the old account on your computer.
iTunes Store: Retrieving and changing passwords (Apple ID) -
Configuration setting that needs to be changed to allow flexibility copy and to paste formatted text
what is the configuration setting in Contribute that needs to be changed to allow me flexibility copy and to paste formatted text?
Example I am unable to copy and paste formatted text within contribute and the line that is represented under the heading below
Research Analysis
This is the research and analysis page. The most recent analysis for all companies listed on theI'm not familiar with 'styled text'- which does not mean much other than it's on a very long list of things I don't know. But I do know you can cut several steps out here:
If your script works so far then you can clean it up:
tell application "FileMaker Developer"
open "MacintoshHD:Users:stuart:Desktop:Practice.fp7"
set mytext to record 2 of table 1 of database 1 as styled text
end tell
tell application "Microsoft Word"
activate
set myRange to create range active document start 0 end 0
insert text (mytext) at myRange
end tell
Also try:
set mytext to contents of record 2 of table 1 of database 1 as styled text
Reese -
Tried my k3772-z modem to connect macbook air to internet and got the message: you can't use this application with this version of mac os x. Is there a setting that needs to be changed?
I can't help you with a direct answer. For third-party devices you should contact the vendor (Vodafone).
If you have an iPhone (or an Android phone with hot-spot capability) you can use that to connect to the Internet without paying for a separate cellular service. -
how do i engage my 8 core mac pro to use all it's cores when using final cut pro and other applications that need processing power? at the moment they seem to be idle...
First, did you use Setup or Migration Assistant? That can happen when coming from a PowerMac or sometimes even from another (Intel) Mac.
Second, wait for the next version of Final Cut due very soon to ship (may have to wait for the ".1" of course to clean up any early issues.
Final Cut Pro - Wikipedia
There are a few apps that are better. I think you can run multiple instances of Handbrake for one.
I've read about and wanted to try PowerDirector 9 (Windows)
PowerDirector 9 video software
video editing software Wiki -
I have hundreds of the same shape that needs to be converted into a symbol for easy editing. Is there a way to do this in Illustrator?
Background here may be relevant: The place I am working is currently using ai CS 3 & 5 and the files in question are converted Freehand files. I have never been a Freehand user, but apparently you were able to swap one shape for another in Freehand. The closest Illustrator equivalent that I am aware of is the symbols panel. I know how to swap one symbol for another, how to create a symbol from a piece of vector art and how to modify a symbol. What I am trying to do is convert several instances of the same object into several instances of the same symbol without having to replace hundreds of objects manually (ie. trying to get the right placement in a grid and everything).
Is there any efficient solution to the task I have in Illustrator CS 3 or CS 5?Try this.
http://illustrator.hilfdirselbst.ch/dokuwiki/en/skripte/javascript/zamena?redirect=1
http://illustrator.hilfdirselbst.ch/dokuwiki/en/skripte/javascript/zamena_size?redirect=1 -
I have two facetime users, both connecting to our enterprise wireless network (Cisco WCS) and they can't make a facetime connection from IPAD to IPAD. Are there any apple protocols or other settings that need to be enabled on WCS? There is no firewall inbetween the two connections, as this is all on our internal network.
Both devices can connect to the network, but when they try to talk to each other they can't make the connection.
Thanks.If anyone ever comes across this and has the same issue, here's what I did to fix it:
My Linksys router has a Network Mode setting, and I had to change it from "Mixed" to "Wireless-G only". (I would've used N but one of the NICs in my house is too old to support it.) Anyway, after making this change, Facetime works fine on the phone. Hope this helps someone else! -
Yesterday I ran Disk Utility and came up with hundreds of permissions that needed repair. I hit the "repair permissions" button and waited until it said they were repaired, but just for fun I hit the "verify permissions" button again, and they all came back! I did this several more times and every time I would hit "verify permissions" I would get the same list. What's up? I've always suspected diagnostic programs, but this is Apple's own!
Ignore them. They aren't errors. You will keep seeing the same ones. As long as you get the message "Permissions repair complete," you're OK.
http://support.apple.com/kb/TS1448?viewlocale=en_US -
My nook app keeps telling me "Please be sure you have internet connectivity, then try again." I am currently connected to wifi and it seems that all my other apps that need to be connect to the internet are properly working. I have turn off my phone, signed off my wifi, installed a new app, but nothing is working. My friend is having similar issues. My phone is up to date. I even tried taking off the wifi in hopes that it could just connect to the 3g but nothing. Not sure if anyone else is experiencieng this issue or knows what I can do. I think that it may be an app problem that needs fixed, but not sure. Help!
Maybe its a Viber problem. As that is not an Apple product, why don't you try and contact the developer?
-
OUI-10091:There are no patches that need to be applied from the patchset
Hi All,
when i try to apply 10.2.0.3 patch on 10.2.0.1 in linux x86 I am getting into this error.
OUI-10091:There are no patches that need to be applied from the patchset Oracle Db 10g R2 Patchset 10.2.0.3.0
The original ora inventory is lost and cannot be recovered.
So is there any way I can upgrade the database software.
Please advise.
thanks in Advance
-PKYou should first try to troubleshoot the missing inventory issue. Check this metalink document:
OUI-67105 Due To Missing Or Corrupted Central Inventory In 10g
Doc ID: Note:417236.1
~ Madrid -
when I try to start outlook for mac, i get the message that there is an old version of the Microsoft Database Daemon that needs to be deleted from the start up files. Where do I find the start up files???
In the Users & Groups pane of System Preferences.
(66105)
Maybe you are looking for
-
After creating the form, I reader enable it. Then a message pops up saying the form cannot be reader enabled. When I try to reader enable it again, it says it's already reader enabled. Users are not able to fill out the form and save it. Only print.
-
How is Last Played calculated?
A song has to play right through before Date Played is changed (I know this because I've watched it happen). However, a little while ago I put a song on pause right at the start in order to watch TV. When I came back to it, the song was still on paus
-
No sound in x86_64 intel(solved snd-usb-audio)
Absolutely no sound.... Am I missing a package. Video plays in mplayer but no sound. Same in dragon. in conf Last edited by lilsirecho (2008-12-01 23:58:53)
-
Well I just discover this awsome feature, so i dicided start using it for fun, so I download several voices. Everything was working perfectly but suddenly the Speech feed back stops working, i always have to close it and wait several minutes or rest
-
Icon in dialog programmin sreen field
hi all, I have a field valflg type char1 and it has values either X or space if it is X i want an OK ICON to be displayed on screen and if space want not ok code there what to do. ITS URGENT . Thanks & Regards, swaroop