Aparte de lo dicho anteriormente, volvamos a tu pregunta original, por si a alguien le puede resultar útil. Yo enfocaría el problema de otra manera, en vez de mandar pixel a pixel, encontraría el rectángulo de la imagen que ha cambiado, lo copiara, lo comprimiría usando jpeg y lo mandaría junto con sus coordenadas. Por otro lado al recibirlo solo tendríamos que dibujar el rectángulo en las coordenadas indicadas. Al comprimir la imagen usando jpeg puede que obtengamos un feo efecto de borde, pero es un mal menor comparada con lo que ganamos en velocidad.
La ventaja son que al enviar un recuadro completo podemos usar formatos de compresión como jpeg, gif o png. La desventaja es que si la imagen tiene muchos cambios repartidos por toda la superficie, el cuadro resultante puede ser prácticamente del mismo tamaño que el original. Es decir, donde realmente se muestra eficaz es en imágenes donde los cambios están localizados en una parte concreta de la pantalla.
Vamos con un poco de código:
Código Delphi
[-]
function Min(i,j: Integer): Integer;
begin
if i < j then
Result:= i
else
Result:= j;
end;
function Max(i,j: Integer): Integer;
begin
if i > j then
Result:= i
else
Result:= j;
end;
procedure Seleccionar(Bitmap1, Bitmap2: TBitmap; var R: TRect);
var
P1, P2: PByte;
i, j: Integer;
begin
R.Right:= 0;
R.Bottom:= 0;
R.Left:= Min(Bitmap1.Width,Bitmap2.Width);
R.Top:= Min(Bitmap1.Height,Bitmap2.Height);
Bitmap1.PixelFormat:= pf24bit;
Bitmap2.PixelFormat:= pf24bit;
for j:= 0 to Min(Bitmap1.Height,Bitmap2.Height) - 1 do
begin
P1:= Bitmap1.ScanLine[j];
P2:= Bitmap2.ScanLine[j];
for i:= 0 to Min(Bitmap1.Width,Bitmap2.Width) - 1 do
begin
if not CompareMem(P1,P2,3) then
begin
R.Right:= Max(i,R.Right);
R.Bottom:= Max(j,R.Bottom);
R.Left:= Min(i,R.Left);
R.Top:= Min(j,R.Top);
end;
inc(P1,3); inc(P2,3);
end;
end;
end;
var
Bitmap1, Bitmap2, Bitmap3: TBitmap;
R: TRect;
begin
Bitmap1:= TBitmap.Create;
Bitmap2:= TBitmap.Create;
Bitmap3:= TBitmap.Create;
try
Bitmap1.LoadFromFile('d:\1.bmp');
Bitmap2.LoadFromFile('d:\2.bmp');
Seleccionar(Bitmap1,Bitmap2,R);
Bitmap3.Width:= R.Right - R.Left;
Bitmap3.Height:= R.Bottom - R.Top;
with Bitmap3 do
Canvas.CopyRect(Rect(0,0,Width,Height),Bitmap2.Canvas,R);
Bitmap3.SaveToFile('d:\3.bmp');
finally
Bitmap1.Free;
Bitmap2.Free;
Bitmap3.Free;
end;
end;
Esta solución se puede mejorar bastante, un posible camino seria utilizar mas de un recuadro, mas pequeños, para localizar los cambios. Pero eso ya es otra historia ...