im trying to send screenshots over socket so i use unsafe pointers to send only the differences:
private unsafe Bitmap GetDiffBitmap(Bitmap bmp, Bitmap bmp2)
{
bmpRes = new Bitmap(1920, 1080,bmp.PixelFormat);
bmData = bmp.LockBits(new Rectangle(0, 0, 1920, 1080), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
bmData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp2.PixelFormat);
bmDataRes = bmpRes.LockBits(new Rectangle(0, 0, bmpRes.Width, bmpRes.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
IntPtr scan0 = bmData.Scan0;
IntPtr scan02 = bmData2.Scan0;
IntPtr scan0Res = bmDataRes.Scan0;
int stride = bmData.Stride;
int stride2 = bmData2.Stride;
int strideRes = bmDataRes.Stride;
int nWidth = bmp.Width;
int nHeight = bmp.Height;
//for(int y = 0; y < nHeight; y++)
System.Threading.Tasks.Parallel.For(0, nHeight, y =>
{
//define the pointers inside the first loop for parallelizing
byte* p = (byte*)scan0.ToPointer();
p += y * stride;
byte* p2 = (byte*)scan02.ToPointer();
p2 += y * stride2;
byte* pRes = (byte*)scan0Res.ToPointer();
pRes += y * strideRes;
for (int x = 0; x < nWidth; x++)
{
//always get the complete pixel when differences are found
if (p[0] != p2[0] || p[1] != p2[1] || p[2] != p2[2])
{
pRes[0] = p2[0];
pRes[1] = p2[1];
pRes[2] = p2[2];
//alpha (opacity)
pRes[3] = p2[3];
}
p += 4;
p2 += 4;
pRes += 4;
}
});
bmp.UnlockBits(bmData);
bmp2.UnlockBits(bmData2);
bmpRes.UnlockBits(bmDataRes);
return bmpRes;
}
this is the call on the client:
private void startSend()
{
Bitmap curr;
Bitmap pre = screenshot();
byte []bmpBytes = imageToByteArray(pre);
SendVarData(handler, bmpBytes);// this is the first send of the whole screen
while (true)
{
curr = screenshot();
Bitmap diff = GetDiffBitmap(pre, curr);//generate differences.
bmpBytes = imageToByteArray(diff);
SendVarData(handler, bmpBytes);//sending the diff image.
pre = curr;
}
}
SendVarData
is a method which send the bytes array over the socket it is not the problem here-leave it.
this is how i get the data in the server side:
public void startListening()
{
Bitmap merge = new Bitmap(1920, 1080);
Graphics g = Graphics.FromImage(merge);
Bitmap prev = byteArrayToImage(ReceiveVarData(client.Client)) as Bitmap;//getting the first full size image.
theImage.Image = prev;//assisning it to picturebox.
while (true)
{
byte[]data = ReceiveVarData(client.Client);
Bitmap curr = byteArrayToImage(data) as Bitmap;//here is the diffrent image
//merge and apply differences
g.DrawImage(prev, 0, 0,1920, 1080);
g.DrawImage(curr, 0, 0, 1920,1080);
theImage.Image = merge;
count++;
prev = merge;
}
}
my problem is that eventhough i merge the two images with the Graphics.Draw it still(after the first dataReceive) looks like not full... this is actually what i see on the server..
i dont know what's wrong here... can anyone light my eyes? :D @DmitriTrofimov
if (p[0] != p2[0] || p[1] != p2[1] || p[2] != p2[2])
{
pRes[0] = p2[0];
pRes[1] = p2[1];
pRes[2] = p2[2];
//alpha (opacity)
pRes[3] = p2[3];
}
else
pRes[0] = 0;
This is what you get when you keep pixel opacity. You should set Alpha to zero on the pixels that are not different and make sure you are working with 32-bit images (refer to PixelFormat
parameter of Bitmap
constructor).
PS Make sure you compress the diff bitmap otherwise it's no use.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.