2010-11-11 74 views
0

我正在創建TCP遠程桌面應用程序 我只想發送先前發送的幀的差異。兩張圖片之間的差異是否大於圖片?

當我比較原始圖像和我把已在ArrayList中 5項中包含的信息的一個像素ArrayList中發生變化的像素信息的第二圖像 第一個項目包含一個高度點 第二項包含一個寬度點 第三項包含RGB.red 第四項包含RGB.Green 的第五項包含RGB.Blue

這是代碼

private void button1_Click(object sender, EventArgs e) 
    { 
     ArrayList new_pixel = Unsafe_diff_array(pictureBox2.Image, pictureBox1.Image); 

     Bitmap new_bit_map = (Bitmap)pictureBox3.Image; 

     for (int i = 0; i < new_pixel.Count; i+=5) 
     { 
      int x = (int)new_pixel[i +1]; 
      int y=(int)new_pixel[i]; 
      int red= Convert.ToInt16(new_pixel[i + 4]) ; 
      int green= Convert.ToInt16(new_pixel[i + 3]) ; 
      int blue=Convert.ToInt16(new_pixel[i + 2]); 
      new_bit_map.SetPixel(x, y, Color.FromArgb(red , green, blue)); 

     } 
     pictureBox3.Image = new_bit_map; 

    } 







    public ArrayList Unsafe_diff_array(Image OrginalImage, Image SecondImage) 
    { 
     Bitmap BOrginalImage = new Bitmap(OrginalImage); 
     Bitmap BSecondImage = new Bitmap(SecondImage); 
     BitmapData bitmapData1 = BOrginalImage.LockBits(new Rectangle(0, 0, 
                 OrginalImage.Width, OrginalImage.Height), 
                 ImageLockMode.ReadOnly, 
                 PixelFormat.Format32bppArgb); 
     BitmapData bitmapData2 = BSecondImage.LockBits(new Rectangle(0, 0, 
                 SecondImage.Width, SecondImage.Height), 
                 ImageLockMode.ReadOnly, 
                 PixelFormat.Format32bppArgb); 

     ArrayList siblings = new ArrayList(); 


     unsafe 
     { 
      byte* imagePointer1 = (byte*)bitmapData1.Scan0; 
      byte* imagePointer2 = (byte*)bitmapData2.Scan0; 

      for (int i = 0; i < bitmapData1.Height; i++) 
      { 

       for (int j = 0; j < bitmapData1.Width; j++) 
       { 
        // write the logic implementation here 

        if ((imagePointer1[0] != imagePointer2[0]) || (imagePointer1[1] != imagePointer2[1]) || (imagePointer1[2] != imagePointer2[2])) 
        { 
         imagePointer2[0] = imagePointer1[0]; 
         imagePointer2[1] = imagePointer1[1]; 
         imagePointer2[2] = imagePointer1[2]; 

         siblings.Add(i); 
         siblings.Add(j); 
         siblings.Add(imagePointer2[0]); 
         siblings.Add(imagePointer2[1]); 
         siblings.Add(imagePointer2[2]); 


        } 

        imagePointer2[3] = imagePointer1[3]; 
        imagePointer1 += 4; 
        imagePointer2 += 4; 


       }//end for j 
       imagePointer1 += bitmapData1.Stride - 
           (bitmapData1.Width * 4); 
       imagePointer2 += bitmapData1.Stride - 
               (bitmapData1.Width * 4); 
      }//end for i 
     }//end unsafe 


     BOrginalImage.UnlockBits(bitmapData1); 
     BSecondImage.UnlockBits(bitmapData2); 

     return siblings ; 
     // return BSecondImage.GetThumbnailImage(SecondImage.Width, SecondImage.Height, null, new IntPtr()); ; 
    } 

問題是當我序列化ArrayList到MemoryStream 我發現尺寸大於圖像 我也試圖把像素的信息在短陣列中改變,但也發現一個尺寸大於圖像的大小!!!!! ?

如何製作此過程以便我可以將縮略圖大小縮小至最小尺寸?

這在我以前序列化的ArrayList

private System.IO.MemoryStream SerializeBinary(object obj){ 
     System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 

     System.IO.MemoryStream memStrm = new System.IO.MemoryStream(); 

     serializer.Serialize(memStrm, obj); 

     return memStrm; 

    } 
+0

是壓縮格式的原始圖像?例如jpg,gif的png?你的陣列將會和該區域的位圖一樣大,如果不是更大的話。此外,數組列表(如果我沒記錯的話)是一個鏈接列表類型集合,因此它可以實時擴展,因此會爲每個像素添加一點點開銷。 – 2010-11-11 13:30:48

+3

我認爲你需要停下來重新考慮你的設計。一個ArrayList,每個像素有5條信息*?你從來沒有**會得到這個表現很好。 – 2010-11-11 13:32:20

回答

2

一個典型的32位WxH圖像使用WxHx4字節的內存(對於一個1024x1024位圖,這是4MB)。

假設您使用16位[x]和[y]和32位[顏色]值以[x] [y] [顏色]格式發送不同像素的列表,並且存在D不同的像素,差異將使用Dx8字節的內存。因此,如果超過一半的像素不同(D> WxH/2),則差異將大於圖像。

對於你的情況,你使用的是一個數組,這意味着[color]實際上表示爲3 [r] [g] [b] 16位值。內存使用量變爲Dx10,如果40%像素髮生變化(D> WxH/2.5),則可以找到閾值。

考慮使用一點來判斷您是發送差異列表還是發送完整圖像,併發送兩者中最小的一個。還要考慮像RLE編碼這樣的事情,使用一個[偏移] 16位值而不是[x]和[y],或者只是將任何未更改的值透明並將結果保存爲PNG格式。

這當然是由運行時插入的任何附加序列化數據以及圖像可以被壓縮的事實(例如PNG是無損的)。

2

當然,這將是更大的代碼!

位圖具有由報頭,像素數據和調色板有時同時一個ArrayList的二進制格式化系列化結果具有一個完全不同的格式,包括組件的元數據,類型metatdata的等

而且它是一個在內存中的結構遺憾的是你所做的所有性能增益在像素上進行不安全的編碼將浪費在拳擊使用ArrayList發生。