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

Вниз

сжатие и отправкакартинки по сети   Найти похожие ветки 

 
night_light ©   (2009-04-20 16:51) [0]

Здравствуйте, подскажите плиз оптимальный путь решения:
есть картинка в памяти (тип TBitmap), необходимо её сжать, чтобы передать по сети, передача несжатых изображений происходит слишком медленно, а передавать надо хотя бы 30 кадров в секунду. Во что лучше сжать, чтобы: 1) быстрее сжалось, 2) сжатое изображение было хотя бы в 5 раз меньше, 3) на приёмном конце прога на делфи относительно просто просто отобразила полученное изображение?


 
clickmaker ©   (2009-04-20 16:56) [1]

ZLib, например.
Или TJPegImage или Intel Jpeg Library
в любом случае, TBitmap - не оптимальный вариант


 
Сергей М. ©   (2009-04-20 16:58) [2]


> есть картинка в памяти (тип TBitmap)


Значит наверняка есть и предыдущая картинка, сделанная на 1/30 секунды ранее.
Остается сравнить эти две картинки, локализовать области, подверженные изменениям, сжать эти изменения и передать приемнику.
Трансляция изменений в подавляющем большинстве случаев несравнимо производительней, чем передачи готовых картинок.


 
night_light ©   (2009-04-20 17:01) [3]


> Сергей М. ©   (20.04.09 16:58) [2]
> > есть картинка в памяти (тип TBitmap)Значит наверняка есть
> и предыдущая картинка, сделанная на 1/30 секунды ранее.Остается
> сравнить эти две картинки, локализовать области, подверженные
> изменениям, сжать эти изменения и передать приемнику.Трансляция
> изменений в подавляющем большинстве случаев несравнимо производительней,
>  чем передачи готовых картинок.


Спасибо, идея хорошая. Остаётся понять, как сжать. :)


 
Palladin ©   (2009-04-20 17:04) [4]

... а, все таки, почему телеграммы из воды сухие выходят


 
Сергей М. ©   (2009-04-20 17:05) [5]


> Остаётся понять, как сжать


Смотря что ты передаешь и что хочешь получить на принимающей стороне...

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

В простейшем случае для незначительно меняющегося во времени изображения вполне может подойти и RLE-алгоритм компрессии/декомпрессии.


 
night_light ©   (2009-04-20 17:11) [6]

TBitmap формат тяжёлый, согласен,
но компонент видеозахвата, который я использую, может выдавать либо TBitmap в память, либо BMP или JPEG, но уже в виде файла для сохранения, а мне нужно передать по сети на другую прогу и там отобразить.
Может можно как-нибудь сохранять, но в память, а оттуда уже передавать по сети на другой комп и там отображать?
И если всё таки конвертировать из TBitmap в другой формат, сжатый, но хранимый в памяти, то во что лучше? Чтобы на приёмном конце не пришлось делать декомпрессию, а как и с TBitmap-ом - просто вывести на Image или некий другой графический компонент.


 
Palladin ©   (2009-04-20 17:13) [7]

gif


 
clickmaker ©   (2009-04-20 17:15) [8]

uses ZLib, TCompressionStream


 
night_light ©   (2009-04-20 17:21) [9]

> Сергей М. ©   (20.04.09 17:05) [5]
> > Остаётся понять, как сжатьСмотря что ты передаешь и что
> хочешь получить на принимающей стороне... Т.е. какого характера
> изменяющееся изображение передается и какого качества изображение
> должно быть восстановлено на принимающей стороне...В простейшем
> случае для незначительно меняющегося во времени изображения
> вполне может подойти и RLE-алгоритм компрессии/декомпрессии.
>

По поводу качества, при сжатии в JPEG фотошопом с уменьшением размера файла где-то в 10 раз, получается картинка с вполне удовлетворяющим в этой задаче качеством.
Вопрос ещё, насколько быстро будет производится JPEG-сжатие? Разрешение 752 на 582, 24 бита на цвет.


 
Сергей М. ©   (2009-04-20 17:31) [10]


> компонент .. может выдавать
> либо TBitmap в память


Этого достаточно.
Режешь битмап тек.кадра на прямоугольные "куски" сравнительно небольшого размера, сравниваешь содержимое каждого "куска" с содержимым соотв. "куска" битмапа предыдущего кадра. При обнаружении несовпадения жмешь изменившийся "кусок", снабжаешь инф.пакет со сжатым "куском" заголовком, отражающим технологические атрибуты "куска" (время, координаты и размер, алг-м сжатия т.п.) и отправляешь инф.пакет приемнику. Имея эту инф-цию приемник проделывает в той же последовательности обратные действия, позволяющие отразить поступившие изменения в некоем своем битмапе.


 
palva ©   (2009-04-20 17:33) [11]

Насколько я понимаю это не отдельные и изображения, а что-то вроде фильма. Так и метод нужно использовать соответствующий. Я слышал краем уха, что для этого используют сжатие с потерями mpeg. Получается файл avi, если я не путаю. Анимированный gif, конечно, тоже можно использовать, но он сжимает без потерь, а значит сохраняет много нюансов, которые можно не сохранять, поскольку они незаметны.


 
night_light ©   (2009-04-20 17:33) [12]

GIF не подходит, сжатие без потерь в моём случае малоэффективно,
передаётся реальная картинка с камеры. И точно повторяющихся участков не будет.

> uses ZLib, TCompressionStream

Спасибо! Такой вопрос, а переменная какого типа хранит в памяти JPEG?
(BMP файл, как я понял, хранится в TBitmap)
И еще, JPEG выводить в Image сразу, без обратной обработки?
Я пока выводил только BMP  в виде TBitmap.


 
Сергей М. ©   (2009-04-20 17:34) [13]

А что сотворяешь-то ? Уж не Remote Desktop ли ?


 
Игорь Шевченко ©   (2009-04-20 17:35) [14]

Киношники блин. Слова "потоковое видео" остались за гранью понимания ?


 
Сергей М. ©   (2009-04-20 17:37) [15]


> передаётся реальная картинка с камеры


Что за камера ?
Может ты вообще не тот огород окучиваешь ?)


 
night_light ©   (2009-04-20 17:38) [16]


> Насколько я понимаю это не отдельные и изображения, а что-
> то вроде фильма. Так и метод нужно использовать соответствующий.
>  Я слышал краем уха, что для этого используют сжатие с потерями
> mpeg. Получается файл avi, если я не путаю.

совершенно правильно понимаете.
но я не знаю, как фильм передавать по сети, а с картинками всё проще,
лью себе через сокеты одну за другой, и всего делов.
но лить понадобилось слишком быстро, гигабитной сети не хватает, вот и возникла проблемка.


 
Сергей М. ©   (2009-04-20 17:42) [17]


> лить понадобилось слишком быстро, гигабитной сети не хватает


Нынче люди с успехом смотрят вполне качественное IPTV, будучи подключенными к провайдеру по 10-мегабитному каналу, а тебе и гигабитного подключения не хватает)


 
night_light ©   (2009-04-20 17:45) [18]


> Что за камера ?

аналоговая камера, 752 на 582, 30 кадров в секунду,
в компе 4-х канальная плата видеозахвата на 120 кадров в сек. суммарно,
в делфе компонент TVideoGrabber,

> Киношники блин. Слова "потоковое видео" остались за гранью
> понимания ?

остались за гранью временных рамок, совершенно некогда разбираться с достижениями прогресса, задача - сжать BMP, желательно одной функцией некой библиотечки, а на другом конце полученную картинку отобразить.

> А что сотворяешь-то ? Уж не Remote Desktop ли ?

отнюдь :) думал, это стандартная задача систем  видеорнаблюдения :(


 
Сергей М. ©   (2009-04-20 17:51) [19]


> задача - сжать ..  а на другом конце полученную картинку отобразить


Т.е. ты считаешь, что транспортная часть будущей "системы" на сквозную ее производительность никак не влияет ?
Иными словами, тебе фиолетово, какой сетевой транспортный протокол при этом использовать ?


 
night_light ©   (2009-04-20 17:56) [20]

уже писал простенькую программку на это счёт, прикидывал, при передаче несжатой картинки через сокеты канал используется почти полностью, вывод - метод передачи сокетами содержит не очень большое количество служебной информации и неплохо использует канал. Если я не прав, поправьте, пожалуйста.
Но по поводу протокола, действительно всё равно, просто с сокетами уже работал.


 
Игорь Шевченко ©   (2009-04-20 17:57) [21]


> в компе 4-х канальная плата видеозахвата на 120 кадров в
> сек. суммарно


ну вот у платы наверняка есть мануал, в котором написано, как передавать видео, а не отдельные картинки. Если не написано, как конкретно передавать, то наверняка стоит ссылка на сайт производителя для обращения за более подробной информацией.


 
Slym ©   (2009-04-20 19:42) [22]

Сергей М. ©   (20.04.09 17:42) [17]
смотрят вполне качественное IPTV

сжатие скорее всго основано на детекте изменения кадров или их части, а не тупое сжатие каждого кадра...
30 jpg в секунду камень нужен мощьный :)
тут сжатие jpg http://delphimaster.net/view/6-1227604925/
очень медленно, быстрее детектить изменение сцены, но на аналоговых шумных камерах нужен хороший алгоритм детекта движения сцены


 
Сергей М. ©   (2009-04-20 19:47) [23]


> Slym ©   (20.04.09 19:42) [22]


> сжатие скорее всго основано на детекте изменения


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

Т.е. алгоритм детекта подает на вход алгоритма сжатия готовые данные - мол, сожми так-то и так-то вот такие-то данные, о происхождении которых тебе, алгоритм сжатия, знать совершенно необязательно


 
аноним   (2009-04-21 15:04) [24]

>... гигабитной сети не хватает, вот и возникла проблемка.
Где же ты был во времена 14400 бит/с, тогда за такое на костре бы спалили


 
AIRDIGER ©   (2009-04-21 15:26) [25]

Жертвую из своих запасов...  не гарантирую что подойдет ....как написал так написал ...

{---------------------------- CompressBufferToBuffer --------------------------}
function CompressBufferToBuffer(InBuffer: Pointer; szInBuffer: integer;
             var OutBuffer; var OutBytes: Integer; Level: Shortint): Boolean;
var
 Buffer: array [1..1024] of byte;
 InMemStrm    : TMemoryStream;
 OutMemStrm   : TMemoryStream;
 CompressStrm : TCompressionStream;
 ByteRaed     : Integer;
begin
 Result := false;
 if (Not Assigned(InBuffer)) or (szInBuffer = 0) then Exit;
 try
   if Level > 3 then Level := 3;
   if Level < 0 then Level := 0;
   InMemStrm    := TMemoryStream.Create;
   OutMemStrm   := TMemoryStream.Create;
   CompressStrm := TCompressionStream.Create(TCompressionLevel(Level),OutMemStrm);
   InMemStrm.Write(InBuffer^, szInBuffer);
   if InMemStrm.Size = 0 then Exit;
   InMemStrm.Position := 0;
   repeat
     ByteRaed := InMemStrm.Read(Buffer,1024);
     CompressStrm.Write(Buffer,ByteRaed);
   until ByteRaed < 1024;

   if OutMemStrm.Size = 0 then Exit;
   OutBytes := OutMemStrm.Size;
   ReallocMem(Pointer(OutBuffer),OutBytes);
   OutMemStrm.Position := 0;
   OutMemStrm.Read(Pointer(OutBuffer)^,OutBytes);

   Result := true;

 finally
   CompressStrm.Free;
   InMemStrm.Free;
   OutMemStrm.Free;
 end;
end;
{--------------------------- DecompressBufferToBuffer -------------------------}
function DecompressBufferToBuffer(InBuffer: Pointer; szInBuffer: Integer;
                              var OutBuffer; var OutBytes: Integer): Boolean;
var
 Buffer: array [1..1024] of byte;
 InMemStrm      : TMemoryStream;
 OutMemStrm     : TMemoryStream;
 DecompressStrm : TDecompressionStream;
 ByteRaed       : Integer;
begin
 Result := False;
 if (Not Assigned(InBuffer)) or (szInBuffer = 0) then Exit;
 try
   InMemStrm      := TMemoryStream.Create;
   OutMemStrm     := TMemoryStream.Create;
   DecompressStrm := TDecompressionStream.Create(InMemStrm);

   InMemStrm.Write(InBuffer^,szInBuffer);
   if InMemStrm.Size = 0 then Exit;
   InMemStrm.Position := 0;

   repeat
     ByteRaed := DecompressStrm.Read(Buffer,1024);
     OutMemStrm.Write(buffer,ByteRaed);
   until ByteRaed < 1024;

   if OutMemStrm.Size = 0 then Exit;
   OutBytes := OutMemStrm.Size;
   ReallocMem(Pointer(OutBuffer), OutBytes);
   OutMemStrm.Position := 0;
   OutMemStrm.Read(POinter(OutBuffer)^,OutBytes);

   Result := true;

 finally
   DecompressStrm.Free;
   InMemStrm.Free;
   OutMemStrm.Free;
 end;
end;



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

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

Наверх




Память: 0.55 MB
Время: 0.012 c
15-1238405776
Alex_2009
2009-03-30 13:36
2009.06.07
windows 2000 пропал доступ к редактору реестра


2-1240403308
dis12345
2009-04-22 16:28
2009.06.07
длинные названия колонок в StringGrid


2-1240244578
Роман
2009-04-20 20:22
2009.06.07
Фильтрация по нескольким полям


2-1240321156
Toha
2009-04-21 17:39
2009.06.07
Анализ имени файла на коректность


15-1238708491
Kerk
2009-04-03 01:41
2009.06.07
Lazarus