[英]c# merge images sent over socket
我試圖通過套接字發送屏幕截圖,所以我使用不安全的指針僅發送差異:
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;
}
這是客戶端上的呼叫:
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
是一種通過套接字發送字節數組的方法, 在這里就不成問題了。
這就是我在服務器端獲取數據的方式:
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;
}
}
我的問題是,盡管我將兩個圖像與Graphics合並。仍然將其繪制(在第一個dataReceive之后)看起來還不完整...這實際上是我在服務器上看到的。
我不知道這是怎么回事...有人可以照亮我的眼睛嗎? :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;
這是保持像素不透明度時得到的。 您應該將相同的像素的Alpha設置為零,並確保您正在使用32位圖像(請參閱Bitmap
構造函數的PixelFormat
參數)。
PS請確保您壓縮diff位圖,否則沒有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.