Форум: "Media";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизВопрос про раскодирование потока с IP камеры Axis (MJPEG) Найти похожие ветки
← →
axwork © (2008-11-25 14:20) [0]Есть камера IP Axis 205
Получаю с нее поток при помощи запроса:
"GET /axis-cgi/mjpg/video.cgi HTTP/1"+#$0d#$0a или
"GET /axis-cgi/jpg/image.cgi HTTP/1"+#$0d#$0a - отдельный кадр
выделяю блок JPG но никак не получается загрузить его в TJpegImage и конвертить в TBitmap для обработки.
TJpegImage говорит что ошибка заголовка Jpeg.
S:=TMemoryStream.Create;
S.WriteBuffer(St[1],Length(St)); //Переброска в stream буфера картинки из St(строка)
S.Seek(0,0);
Jpg:=TJpegImage.Create;
Jpg.LoadFromStream(S); //Ошибка происходит здесь
Jpg.SaveToFile("C:\1.jpg");
Jpg.Free;
Info.Source.Assign(Jpg); //Конвертация в TBitmap
S.Free;
Похоже что передаётся некорректный Jpeg...
Помогите разобраться с этим форматом... мож там что дописать нужно в блок или подменить...
← →
Сергей М. © (2008-11-25 14:24) [1]
> St[1]
St - это что, строка ?
← →
Сергей М. © (2008-11-25 14:26) [2]Как у тебя в строковой переменной оказались данные заведомо ожидаемого нестрокового формата ?
← →
axwork © (2008-11-25 14:41) [3]Помоему строки позволяют хранить массив байт... так что St: String с буфером полученных байт из камеры по HTTP запросу...
var
error : integer;
buf : array [0..1023] of Char;
str : string;
...
str:="GET /axis-cgi/jpg/image.cgi HTTP/1.0"#13#10#13#10;
send(sock, str[1], Length(str), 0);
ZeroMemory(@Buf,1024);
error:=recv(sock,Buf,1024,0);St:="";
while (error>0) and (CamProperty[Info.CamNum].EnabledCam) and (Info.State<>thsFree) do
begin
St:=St+Copy(buf,0,error);
error:=recv(sock,buf,1024,0);
end;
← →
Сергей М. © (2008-11-25 14:47) [4]
> St:=St+Copy(buf,0,error);
ты справку к ф-ции Copy вообще читал ?
← →
axwork © (2008-11-25 14:56) [5]Спасибо за наводку ... похоже дело действительно в этом.
← →
Сергей М. © (2008-11-25 14:57) [6]
> похоже дело действительно в этом
И не только в этом.
← →
DVM © (2008-11-25 22:25) [7]
> axwork © (25.11.08 14:56) [5]
Дарю класс. Принимай данные в этот буфер.
{******************************************************************************}
{* *}
{* CamBuff *}
{* (с) 2005-2008 Дмитрий Муратов (dvmuratov@yandex.ru) *}
{* Версия 2.1 8/10/2008 *}
{* *}
{******************************************************************************}
unit CamBuff;
interface
type
TBuffer = class(TObject)
private
FStorage: PAnsiChar;
FAllocation: integer;
FHead: PAnsiChar;
FTail: PAnsiChar;
FSize: integer;
function GetSize: integer;
procedure SetSize(ASize: integer);
function GetHead: PAnsiChar;
function GetStorage: PAnsiChar;
function GetTail: PAnsiChar;
public
constructor Create; overload;
constructor Create(ASize: integer); overload;
constructor Create(AStorage: PAnsiChar; ASize: integer); overload;
constructor Create(ABuffer: TBuffer); overload;
destructor Destroy; override;
function AppendBuff(ABuffer: TBuffer): integer;
function Append(AStorage: PAnsiChar; ASize: integer): integer;
function Assign(AStorage: PAnsiChar; ASize: integer): integer;
function AssignBuff(ABuffer: TBuffer): integer;
function Consume(ACount: integer): integer;
procedure Emply;
function IsEmpty: boolean;
function Expand(ACount: integer): integer;
function Extract(ASize: integer): PAnsiChar;
function Shrink(ACount: integer): integer;
property Head: PAnsiChar read GetHead;
property Size: integer read GetSize write SetSize;
property Storage: PAnsiChar read GetStorage;
property Tail: PAnsiChar read GetTail;
end;
← →
DVM © (2008-11-25 22:25) [8]
implementation
//------------------------------------------------------------------------------
constructor TBuffer.Create;
begin
FAllocation := 0;
FSize := 0;
GetMem(FStorage, FAllocation);
FHead := FStorage;
FTail := FHead;
end;
//------------------------------------------------------------------------------
constructor TBuffer.Create(ASize: integer);
begin
FAllocation := ASize;
FSize := ASize;
GetMem(FStorage, FAllocation);
FHead := FStorage;
FTail := FHead;
end;
//------------------------------------------------------------------------------
constructor TBuffer.Create(AStorage: PAnsiChar; ASize: integer);
begin
FAllocation := ASize;
FSize := ASize;
GetMem(FStorage, FAllocation);
FHead := FStorage;
Move(AStorage^, FStorage^, ASize);
FTail := FHead + FSize;
end;
//------------------------------------------------------------------------------
constructor TBuffer.Create(ABuffer: TBuffer);
begin
FAllocation := ABuffer.Size;
FSize := ABuffer.Size;
GetMem(FStorage, FAllocation);
FHead := FStorage;
Move(ABuffer.Storage^, FStorage^, ABuffer.Size);
FTail := FHead + FSize;
end;
//------------------------------------------------------------------------------
function TBuffer.GetSize: integer;
begin
result := FSize;
end;
//------------------------------------------------------------------------------
procedure TBuffer.SetSize(ASize: integer);
begin
if FSize < ASize then Expand(ASize) else FSize := ASize;
end;
// Отсекает первые ACount символов ----------------------------------------------
function TBuffer.Consume(ACount: integer): integer;
begin
if ACount > FSize then ACount := FSize;
FHead := FHead + ACount;
FSize := FSize - ACount;
Result := ACount;
end;
// Отсекает последние ACount символов -------------------------------------------
function TBuffer.Shrink(ACount: integer): integer;
begin
if ACount > FSize then ACount := FSize;
FSize := FSize - ACount;
if FTail > FHead + FSize then FTail := FHead + FSize;
Result := ACount;
end;
// Расширение буфера -----------------------------------------------------------
function TBuffer.Expand(ACount: integer): integer;
var
Spare, HeadSpace, TailSpace, Width, OldAllocation: integer;
NewStorage: PAnsiChar;
begin
// Находим свободный (незанятый) объем буфера
Spare := FAllocation - FSize;
// Вычисляем свободное место в начале буфера
HeadSpace := FHead - FStorage;
// Вычисляем свободное место в конце буфера
TailSpace := Spare - HeadSpace;
// Вычисляем размер (ширину) занятой части буфера
Width := Tail - Head;
// Если в буфере есть достаточно свободного места для добавления count символов
if Spare > ACount then
begin
// Если в конце бефера свободного места меньше чем надо добавить
if TailSpace < ACount then
begin
// Двигаем полезные данные в начало буфера
Move(FHead^, FStorage^, FSize);
// Теперь начало полезных данных совпадает с началом буфера
FHead := FStorage;
// Корректируем указатель на свободное место в конце буфера
FTail := FHead + Width;
end;
end
else
// Если в буфере недостаточно места для добавления count символов
begin
OldAllocation := FAllocation;
// Общий объем буфера увеличиваем на count
FAllocation := FAllocation + ACount;
// Создаем временный буфер нужного размера
GetMem(NewStorage, FAllocation);
FillChar(NewStorage^, FAllocation, 0);
if FStorage <> nil then
begin
// Копируем в него данные из старого буфера
Move(FHead^, NewStorage^, FSize);
// Старый буфер удаляем
FreeMem(FStorage, OldAllocation);
end;
// Новый буфер заменяет старый
FStorage := NewStorage;
// Данные в начале буфера
FHead := FStorage;
// Хвоcт на расстоянии width от головы буфера
FTail := FHead + Width;
end;
// Устанавливаем новый размер буфера
FSize := FSize + ACount;
// Возвращаем новый размер
result := FSize;
end;
// Добавление данных в конец буфера --------------------------------------------
function TBuffer.Append(AStorage: PAnsiChar; ASize: integer): integer;
begin
Expand(ASize);
Move(AStorage^, FTail^, ASize);
FTail := FTail + ASize;
result := FSize;
end;
// Добавление данных в конец буфера --------------------------------------------
function TBuffer.AppendBuff(ABuffer: TBuffer): integer;
begin
result := Append(ABuffer.Storage, ABuffer.Size);
end;
// Извлечение первых ASize символов с их удалением из буфера ------------------
function TBuffer.Extract(ASize: integer): PAnsiChar;
var
OldHead: PAnsiChar;
begin
if ASize > FSize then ASize := FSize;
OldHead := FHead;
FHead := FHead + ASize;
FSize := FSize - ASize;
result := OldHead;
end;
//------------------------------------------------------------------------------
function TBuffer.GetHead: PAnsiChar;
begin
result := FHead;
end;
//------------------------------------------------------------------------------
function TBuffer.GetStorage: PAnsiChar;
begin
result := FStorage;
end;
//------------------------------------------------------------------------------
function TBuffer.GetTail: PAnsiChar;
begin
result := FTail;
end;
//------------------------------------------------------------------------------
procedure TBuffer.Emply;
begin
FSize := 0;
FHead := FStorage;
FTail := FHead;
end;
//------------------------------------------------------------------------------
function TBuffer.Assign(AStorage: PAnsiChar; ASize: integer): integer;
begin
FreeMem(FStorage, FAllocation);
FSize := ASize;
FAllocation := FSize;
GetMem(FStorage, FAllocation);
FHead := FStorage;
Move(AStorage^, FStorage^, FSize);
FTail := FHead + FSize;
result := FSize;
end;
//------------------------------------------------------------------------------
function TBuffer.AssignBuff(ABuffer: TBuffer): integer;
begin
result := Assign(ABuffer.Storage, ABuffer.Size);
end;
//------------------------------------------------------------------------------
function TBuffer.IsEmpty: boolean;
begin
result := FSize = 0;
end;
//------------------------------------------------------------------------------
destructor TBuffer.Destroy;
begin
FreeMem(FStorage, FAllocation);
inherited Destroy;
end;
//------------------------------------------------------------------------------
end.
← →
DVM © (2008-11-25 23:14) [9]
> axwork © (25.11.08 14:20)
> выделяю блок JPG
Кстати, как выделяешь то? Сдается мне, что строковыми функциями пользуешься?
Страницы: 1 вся ветка
Форум: "Media";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.107 c