Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.03.2011, 19:27   #1
Loadx
 
Регистрация: 03.12.2010
Сообщений: 8
Вопрос Изображение по UDP

Доброго времени суток.

Вот набросал Клиент и сервер на основе IdUDP.

Клиент

Код:
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, IdUDPServer, XPMan, IdBaseComponent, IdComponent, IdUDPBase,
 IdUDPClient, StdCtrls, IdSocketHandle,Jpeg, ExtCtrls;

type
 TForm1 = class(TForm)
   IdUDPClient1: TIdUDPClient;
   Button1: TButton;
   Image1: TImage;
   Memo: TMemo;
   procedure Button1Click(Sender: TObject);
   procedure GrabScreen();
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
    Bitmap:TBitmap;
    Jpeg:TJpegImage;
    packNUM:integer;
implementation

{$R *.dfm}

procedure TForm1.GrabScreen();
var
DC : HDC;
bmp : TBitmap;
jpgImg: TJPEGImage;
Stream:TMemoryStream;
size:integer;
Buf:array[0..1024] of byte;
begin
Stream:=TMemoryStream.Create;
bmp := TBitmap.Create;
jpgImg := TJPEGImage.Create;
bmp.Height := Screen.Height;
bmp.Width := Screen.Width;
DC := GetDC(0);
bitblt(bmp.Canvas.Handle, 0, 0, Screen.Width, Screen.Height, DC, 0, 0, SRCCOPY);
ReleaseDC(0, DC);
jpgImg.Assign(bmp);
jpgImg.CompressionQuality:=100;

jpgImg.SaveToStream(Stream);

    Stream.Position:=0;
    size:=Stream.Size;
    IdUDPClient1.Send('text'+IntToStr(Size));
    packNUM:=0;
    while Stream.Position<Stream.Size do
   begin
      packNUM:=packNUM+1;
      size:=Stream.Read(Buf,SizeOf(Buf));
      IdUDPClient1.SendBuffer(Buf,size);
      Memo.Lines.Add(IntToStr(Stream.Position)+' < '+IntToStr(Stream.Size)+'  пакет №  '+IntToStr(packNUM));
  end;

bmp.Assign(jpgImg);
jpgImg.Free;
 Form1.Image1.Picture.Bitmap.Assign(bmp);
 bmp.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
GrabScreen();
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Bitmap:=TBitmap.Create;
  Jpeg:=TJpegImage.Create;
end;

end.
Loadx вне форума Ответить с цитированием
Старый 27.03.2011, 19:27   #2
Loadx
 
Регистрация: 03.12.2010
Сообщений: 8
По умолчанию

Сервер

Код:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Forms,
ExtCtrls, StdCtrls, ScktComp, Controls,dialogs, ComCtrls,
IdUDPServer, XPMan, IdBaseComponent, IdComponent, IdUDPBase,
 IdUDPClient, IdSocketHandle, math, Jpeg;

type
 TForm1 = class(TForm)
   IdUDPServer1: TIdUDPServer;
   Memo: TMemo;
   Image1: TImage;
   Button1: TButton;
   procedure IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
     ABinding: TIdSocketHandle);
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 toread:integer;
 MainSize:integer;
   Size:integer;
   proverka:integer;
     StrStream  : TStringStream;
 MemStream  : TMemoryStream;
 packNUM:integer;
implementation

{$R *.dfm}

procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
 ABinding: TIdSocketHandle);

var
  Buf:array[0..1023] of byte;
   Jpeg:TJpegImage;
      Bitmap:TBitmap;

begin
 // здесь происходит обработка данных пришедших от клиента
//все что длинной до 10  я считаю текстом, а что
 // больше 10, то это уже изображение

 if AData.Size<=10 then
 begin
 packNUM:=0;
   // итак к нам пришел текст (размер изображения), работаем с потоком строк
   // создаем строковый поток
   StrStream:=TStringStream.Create('');
   // читаем данные в этот поток из пришедшего потока
   StrStream.CopyFrom(AData, AData.Size);
   // добавляем данные в приемник, указывая перед этим от кого этот текст
   Memo.Lines.Add(ABinding.PeerIP+': '+copy(StrStream.DataString,5,length(StrStream.DataString)));

   //Переменная, хранящая размер изображения
   MainSize:=StrToInt(copy(StrStream.DataString,5,length(StrStream.DataString)));

   // освобождаем память
   StrStream.Free;

   // Поток для изображения
   MemStream:= TMemoryStream.Create;
    MemStream.Size:=MainSize;
    MemStream.Position:=0;
      ToRead:=MemStream.Size-MemStream.Position;
      ToRead:=Min(ToRead,AData.size);

 end else

// Прием изображения

 begin
// Memo.Lines.Add(IntToStr(Adata.Size));
      if (ToRead>0) then
      begin
        packNUM:=packNUM+1;
        Size:=Adata.Size;
        if Size<0 then exit;
        MemStream.WriteBuffer(Adata,Size);
        ToRead:=MemStream.Size-MemStream.Position;
        ToRead:=Min(ToRead,Adata.Size);
        Memo.Lines.Add(IntToStr(Adata.Size) + '  пакет №  '+IntToStr(packNUM));
      end;
 end;
end;

//Кнопка, которая должна поместить изображение в image1

procedure TForm1.Button1Click(Sender: TObject);
var
      Jpeg:TJpegImage;
      Bitmap:TBitmap;
begin
MemStream.Position:=0;
      Jpeg:=TJpegImage.Create;
      Bitmap:=TBitmap.Create;
      try
        Jpeg.LoadFromStream(MemStream);
        Jpeg.SaveToFile('C:\Screenshot.jpg');
        Bitmap.Assign(Jpeg);
      finally
      Form1.Image1.Picture.Bitmap.Assign(Bitmap);
        Jpeg.Free;
        Bitmap.Free;
      end;
end;

end.
Клиент отсылает изображение на сервер, послав предварительно размер изображения. Компоненты Memo я добавил просто для отслеживания отосланных и принятых пакетов и их размеров.

Все отсылается и доходит, при нажатии на кнопку принятое изображение должно поместиться в Jpeg, но выдает ошибку Jpeg 53 (неверный формат).
возможно я не вижу банальной ошибки...
Loadx вне форума Ответить с цитированием
Старый 27.03.2011, 21:00   #3
Loadx
 
Регистрация: 03.12.2010
Сообщений: 8
По умолчанию

Все, ошибку устранил сам, извините за беспокойство
Loadx вне форума Ответить с цитированием
Старый 09.04.2011, 17:23   #4
Artorios
 
Регистрация: 04.10.2010
Сообщений: 3
По умолчанию

А скажи,как исправил?Пожалуйста
Artorios вне форума Ответить с цитированием
Старый 15.04.2011, 14:44   #5
Loadx
 
Регистрация: 03.12.2010
Сообщений: 8
По умолчанию

Нельзя было считывать напрямую из AData в поток, необходимо было с начало из AData считать в буффер (переменная Buf (размер на сервере надо изменить 0..1024, либо на клиенте 0..1023 (последнее будет более правильно с точки зрения размеров))), а потом уже записать буффер в поток MemStream.

Код:
        packNUM:=packNUM+1;
        Adata.Read(Buf,sizeof(Buf));
        if Size<0 then exit;
        MemStream.WriteBuffer(Buf,sizeof(Buf));
        Memo.Lines.Add(IntToStr(MemStream.Position));
Для одиночной передачи изображения условие ToRead можно снести, понадобится когда будет отсылаться не одно изображение, а множество, т.е. онлайн просмотр рабочего стола.
Loadx вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
UDP сниффер XAOC-forever Работа с сетью в Delphi 3 11.07.2011 22:14
прочитать UDP AmonRa Работа с сетью в Delphi 0 22.11.2010 06:32
Проблема с UDP Kirill666 Работа с сетью в Delphi 3 22.03.2007 21:55