the difference between two images is larger than the images?
I am in the process of creating a TCP remote desktop application i want to send only the difference of the previously sent frame.
When I compare the original image and the second image I put information of pixels that have changed in ArrayList five Item in the ArrayList containing information one pixel The first Item contains a Height point The second Item contains a Width point The third Item contains RGB.red The fourth Item contains RGB.Green The Fifth Item contains RGB.Blue
This is the code
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;
}//e开发者_Go百科nd 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()); ;
}
the problem is when i Serialize ArrayList to MemoryStream I find that the size larger than the images I have also tried to put information of pixels that changed in Short Array, but also found a size larger than the images !!!!!?
How do I make this process so that I can Thumbnail size to the smallest possible size ?
the code which i used to Serialize 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;
}
A typical 32-bit WxH image uses WxHx4 bytes of memory (that's 4MB for a 1024x1024 bitmap).
Assuming that you're sending the list of different pixels in [x][y][color] format with 16-bit [x] and [y] and a 32-bit [color] value, and there are D different pixels, the difference will use Dx8 bytes of memory. Thus, the difference will be larger than the image if more than half the pixels are different (D > WxH/2).
In your case, you're using an array, which means that [color] is actually represented as three [r][g][b] 16-bit values. The memory usage becomes Dx10 and the threshold can be found if 40% pixels have changed (D > WxH/2.5 ).
Consider using a bit to tell whether you're sending a list of differences or a full image, and send the smallest of the two. Also consider things like RLE encoding, using a single [offset] 16-bit value instead of [x] and [y], or just making any unchanged values transparent and saving the result in PNG format.
This, of course, is compounded by any additional serialization data is inserted by your runtime, and the fact that images can be compressed (PNG is lossless, for instance).
Of course it will be larger!
Bitmap has an in-memory structure consisting of header, pixel data and sometimes palette while binary formatter serialization result of an ArrayList has a totally different format consisting of assembly metadata, type metatdata, etc.
Also it is a pity all your performance gain of doing unsafe coding on pixels will be wasted on boxing happening of using ArrayList.
精彩评论