Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.10.16;
Скачать: CL | DM;

Вниз

Использ. ZLIB для сжатия файла при передаче сервер-клиент   Найти похожие ветки 

 
Pcrepair ©   (2011-06-28 19:07) [0]

Использование библиотеки Zlib для компрессии-декомпрессии графического файла (BMP) при передаче по сети с использованием архитекруры сервер-клиент на базе INDY10

Есть сервер, делает  по запросу клиента захват видеобуфера в формат BMP, записывает в ОЗУ, и передает через сетевой сокет клиенту. Проблема в том что сетевой адаптер загружается по максимуму (частота обращения к серверу 40 мс). надо както сжать передаваемые по сети данные.
вот код сервера (немного упрощенная версия, все лишнее отброшено)

unit main;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, IdContext, StdCtrls, IdBaseComponent, IdComponent, IdCustomTCPServer,
 IdTCPServer, ExtCtrls, Zlib;

type
 TForm1 = class(TForm)
   IdTCPServer1: TIdTCPServer;
   IPadress: TEdit;
   PortNumber: TEdit;
   Button1: TButton;
   Memo1: TMemo;
   Image1: TImage;
   procedure Button1Click(Sender: TObject);
   procedure IdTCPServer1Execute(AContext: TIdContext);
   //procedure Compress(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
   procedure Log(S:string);
   procedure GET_SCREEN;
 end;

var
 Form1: TForm1;
 pic : TMemoryStream; //ГлобПЕРЕМ в которой хранится данные скрина экрана

implementation

{$R *.dfm}

procedure TForm1.GET_SCREEN; //Процедура получения скрина экрана
var
 Desktop: TCanvas;
 B: TBitmap;
 W, H :Integer;
 Kursor:TPoint;
 TempRect:TRect;
begin
GetCursorPos(Kursor);
W:=Screen.Width;
H:=screen.Height;
TempRect:=Rect(Kursor.x,Kursor.y,Kursor.x+10,Kursor.y+10);
B:=TBitmap.Create;
B.Width:=W;
B.Height:=H;

Desktop:=TCanvas.Create;
try
 with Desktop do
  Handle := GetWindowDC(GetDesktopWindow);
  with B.Canvas do
   begin
    Brush.Color:=clGreen;
    CopyRect (Rect (0, 0, w, h),
              DeskTop,
              Rect (0, 0, w, h));
    FillRect(TempRect);
   end;
  FreeAndNil(pic);
  pic := TMemoryStream.create; //вот тут данные размещаются в ОЗУ
    B.SaveToStream(pic);
finally
 DeskTop.Free;
 B.Free;
end;
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext); //Процедура передачи данных клиенту
var
 z: string;
 X,Y:integer;

 K:TPoint;
begin
 with AContext.Connection do
 begin
  z := AContext.Connection.IOHandler.ReadLn;
  if SameText(Copy(z, 1, 11), "get_screen ") then
  begin
   Log("Запрошен скриншот");
   GET_SCREEN;
     AContext.Connection.IOHandler.WriteBufferOpen(pic.Size);
   Log("Передаем файл s.bmp");

   AContext.Connection.IOHandler.Write(pic);
   Log("Файл передан");
   AContext.Connection.IOHandler.Close;
  end;

  if SameText(Copy(z, 1, 11), "mouse_move ") then
  begin
   z := AContext.Connection.IOHandler.ReadLn;
   if SameText(Copy(z, 1, 8), "mouse_x ") then
   X:=StrToInt(Copy(z,9,4));

   z := AContext.Connection.IOHandler.ReadLn;
   if SameText(Copy(z, 1, 8), "mouse_y ") then
   Y:=StrToInt(Copy(z,9,4));

   Log("Перемещение мыши");
   SetCursorPos(X,Y);
 end;

 if SameText(Copy(z, 1, 11), "mouse_left ") then
  begin
   GetCursorPos(K);
   mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN,K.X,K.Y,0,0);
   mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP,K.X,K.Y,0,0);
   Log("Нажатие левой кнопки мыши");
  end;

  if SameText(Copy(z, 1, 12), "mouse_right ") then
  begin
   GetCursorPos(K);
   mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_RIGHTDOWN,K.X,K.Y,0,0);
   mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_RIGHTUP,K.X,K.Y,0,0);
   Log("Нажатие правой кнопки мыши");
  end;

 AContext.Connection.Disconnect;
end;
end;
end.


В общем и целом все работает
Вопрос:
как тут прикрутить сжатие ПЕРЕМ pic в момент передачи ее клиенту по сети с помощью TCompressionStream от ZLib.pas
использование трансформации *.bmp в другие форматы типа *.png не обсуждается, нужен формат файла BMP (для последующей обработки OCR)


 
Ega23 ©   (2011-06-28 19:12) [1]


> как тут прикрутить сжатие ПЕРЕМ pic в момент передачи ее
> клиенту по сети с помощью TCompressionStream от ZLib.pas

Взять и сжать, какие проблемы-то?
З.Ы. Код - Адъ и Содомiя


 
Pcrepair ©   (2011-06-28 19:21) [2]

вижу, ЕГА23, ты сильно продвинутая
напиши код, если все так просто


 
Ega23 ©   (2011-06-28 19:36) [3]


> вижу, ЕГА23, ты сильно продвинутая


Да, я такая


> напиши код, если все так просто


1. Версия delphi не указана. А различия в использовании ZLib.pas есть. Небольшие, но есть.
2. Я по вторникам не подаю.
3. with AContext.Connection do
begin
 z := AContext.Connection.IOHandler.ReadLn;

Жжош напалмом.


 
Pcrepair ©   (2011-06-28 19:38) [4]

ну не можеш или не хочешь чего в ветку "начинающим" влезла?
иди уже к продвинутым с ними меряйся чем там у тебя


 
Ega23 ©   (2011-06-28 19:43) [5]


> иди уже к продвинутым с ними меряйся чем там у тебя


Не говори мне, что делать, а я тебе не скажу, куда пойти.


 
Pcrepair ©   (2011-06-28 19:57) [6]

тебе было сказано куда идти, а не что делать
че то в голове у тебя все спуталось, а может ты буквы читать не умеешь?


 
Ega23 ©   (2011-06-28 20:04) [7]


> тебе было сказано куда идти, а не что делать


1. Малыш. Тебе уже было сказано, что без озвучивания версии Delphi твой вопрос несколько некорректен.
2. ZCompressStream-ZDecompressStream под D2010 работает с ошибкой. При упаковке определённого бинарника с сжатием по-умолчанию, при его последующей распаковке вылетает ошибка. Бинарник могу привести в качестве примера. Это из-за глюка самой ZLib. Лично я использовала ZCompress/ZDecompress, пока ошибок не встретилось.
3. Да, я не умею читать, не умею писать, в голове моей опилки. А что такое буквы?


 
Pcrepair ©   (2011-06-28 20:22) [8]

если бы бландинки были повнимательнее, оне бы заметили ужастные буквы INDY10 в самом начале темы. впрочем бландинки могуть и не знать что INDY10 входит в комплект D2010
и откуда взялось
> ZCompressStream-ZDecompressStream под D2010 работает с ошибкой

в теории сказано:
Модуль Zlib.pas предоставляет нам два класса-потока:
TCompressionStream Х TDecompressionStream
придумываем на ходу?


 
antonn (work)   (2011-06-28 20:28) [9]

попробуй http://desksoft.ru/index.php?forum&p_id=1062#post_1062
Ega23 - не она


 
Ega23 ©   (2011-06-28 20:36) [10]


> если бы бландинки были повнимательнее, оне бы заметили ужастные
> буквы INDY10 в самом начале темы. впрочем бландинки могуть
> и не знать что INDY10 входит в комплект D2010


Если бы мальчики Алексеи были повнимательнее, то увидели бы значок © возле моего ника, нажав на который прочитали бы, что зовут меня Егоров Олег Вячеславович и мне 35 лет. Но тебя же никто не заставляет такой квест проходить, нес па?
А что касается INDY10, то я вот точно такую же директорию наблюдаю у себя в сорцах и к 2007 и к 2010. Что на мой взгляд вполне может быть, т.к. INDY это INDY, а DELPHI это DELPHI.

> Модуль Zlib.pas предоставляет нам два класса-потока:

Тебе уже несколько раз сказали, что нужно версию Delphi указать. Разные zlib.pas у них, понимаешь? РАЗ-НЫ-Е.
Для 2007:
 TCustomZlibStream = class(TStream)
 TCompressionStream = class(TCustomZlibStream)
 TDecompressionStream = class(TCustomZlibStream)


Для 2010:
кроме классов ещё и
procedure ZCompressStream(inStream, outStream: TStream;
 level: TZCompressionLevel = zcDefault); overload;
// CG: Add overload to take old enum type
procedure ZCompressStream(inStream, outStream: TStream;
 level: TCompressionLevel); overload; inline;

procedure ZDecompressStream(inStream, outStream: TStream);


Впрочем, надоело.


 
Pcrepair ©   (2011-06-28 20:42) [11]

antonn (work), спасибо за наводку
там что? удаленный доступ к хосту через ВЕБ-интерфейс?

но мне нужны не сами процедуры компресии-декомпресии (их примеров есть много), мне неясно как содержимое ОЗУ в ПЕРЕМ pic сжать в момент передачи потока в сокет
ну ясно, надо написать саму процедуру с использованием модуля Zlib (надеюсь с ним все нормально, без глюков), затем... вызвать эту процедуру....
надо.... тут неясно как обернуть ПЕРЕМ этой процедурой. как все это написать. синтаксис


 
antonn (work)   (2011-06-28 20:45) [12]

там просто сайт.
я использую две функции для упаковки/распаковки, передается в tmemorystream, возвращается уже сжатый, это надо?


 
Ega23 ©   (2011-06-28 20:48) [13]


> я использую две функции для упаковки/распаковки, передается
> в tmemorystream, возвращается уже сжатый, это надо?


Ты сам стрим пакуешь, или его Memory? Там реальный косяк есть, я на него в начале года наткнулся.


 
antonn (work)   (2011-06-28 20:53) [14]

то, что сжимается через TCompressionStream


 
Pcrepair ©   (2011-06-28 20:55) [15]

antonn (work)
нет наверно, не это
еще раз
сервер по запросу клиента получает скрин экрана
сервер размещает полученный поток данных в ОЗУ

FreeAndNil(pic); // тут обнуляется и удаляется предыдущие данные в ОЗУ
  pic := TMemoryStream.create;// тут создаем ПЕРМ
    B.SaveToStream(pic);  //вот тут данные размещаются в ОЗУ

сервер передает данные в клиент

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


 
antonn (work)   (2011-06-28 20:57) [16]

FreeAndNil(pic); // тут обнуляется и удаляется предыдущие данные в ОЗУ
pic := TMemoryStream.create;// тут создаем ПЕРМ
B.SaveToStream(pic);
Pack_Memory(B);
посылаем в сеть B.


 
antonn (work)   (2011-06-28 20:58) [17]

не то скопипастил :)
FreeAndNil(pic); // тут обнуляется и удаляется предыдущие данные в ОЗУ
pic := TMemoryStream.create;// тут создаем ПЕРМ
B.SaveToStream(pic);
Pack_Memory(pic);
посылаем в сеть pic.CODE>


 
antonn (work)   (2011-06-28 21:00) [18]

хочу заметить что вот этот вот Pack_Memory() ниразу не оптимален внутрях


 
Pcrepair ©   (2011-06-28 21:13) [19]

ага....
то есть
Pack_Memory - это та самая процедура, которую еще надо написать, чтоб нормально еще и работала, которая вызывается и которая сжимает поток pic?

что касается -
> вот этот вот Pack_Memory() ниразу не оптимален внутрях

но работать то будет? оптимизация - следующий этап
Я уже заметил что эти простенькие программы (сервер и клиент) при работе жрут до 30% мощности ПРОЦА (интел4 два ведра)
узкие места будем разбирать отдельно


 
Anatoly Podgoretsky ©   (2011-06-28 21:22) [20]


> 2. Я по вторникам не подаю.

Пусть приходит в пятницую



Страницы: 1 вся ветка

Текущий архив: 2011.10.16;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.009 c
2-1308890972
Wryyyyyy
2011-06-24 08:49
2011.10.16
Query.Parameters


2-1309442338
Pcrepair
2011-06-30 17:58
2011.10.16
Программа "ест" память, потом сбой


15-1308601797
Юрий
2011-06-21 00:29
2011.10.16
С днем рождения ! 21 июня 2011 вторник


2-1308936747
vegarulez
2011-06-24 21:32
2011.10.16
как правильно вставить декларацию процедуры?


2-1309343844
bon
2011-06-29 14:37
2011.10.16
delphi & c#