简体   繁体   中英

c# merge images sent over socket

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM