Модераторы: Snowy, Alexeis, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема со сборкой avi 
V
    Опции темы
Predator_2004
Дата 1.2.2008, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 85
Регистрация: 26.4.2007

Репутация: нет
Всего: нет



Приветствую всех обитателей форума!
Делаю следующее: есть 251 bmp картинка 32 бит на пиксель. Эти картинки являются кадрами. Нужно из них собрать видеофайл avi. Выполнил двумя способами:
1)
Код

procedure BuildAvi(List:TStringList; FileName:string);
var
  i: Integer;
  pfile: PAVIFile;
  asi: TAVIStreamInfo;
  ps: PAVIStream;
  nul: Longint;

  BitmapInfo: PBitmapInfoHeader;
  BitmapInfoSize: Integer;
  BitmapBits: Pointer;
  BitmapSize: Integer;
begin
      AVIFileInit;
      DeleteFile(FileName);
      if AVIFileOpen(pfile, PChar(FileName), OF_WRITE or OF_CREATE, nil)=AVIERR_OK then
      begin
        FillChar(asi,sizeof(asi),0);

        asi.fccType := streamtypeVIDEO;                //  Now prepare the stream
        asi.fccHandler := 0;
        asi.dwScale := 1;
        asi.dwRate :=25;

        with List.Objects[0] as TBitmap do
        begin
          InternalGetDIBSizes(Handle,BitmapInfoSize,dword(BitmapSize),256);
          BitmapInfo := AllocMem(BitmapInfoSize);
          BitmapBits := AllocMem(BitmapSize);
          InternalGetDIB(Handle,0,BitmapInfo^,BitmapBits^,256);
        end;

        asi.dwSuggestedBufferSize := BitmapInfo^.biSizeImage;
        asi.rcFrame.Right := BitmapInfo^.biWidth;
        asi.rcFrame.Bottom := BitmapInfo^.biHeight;

        if AVIFileCreateStream(pfile,ps,asi)=AVIERR_OK then
          with (List.Objects[0] as TBitmap) do
          begin
            InternalGetDIB(Handle,0,BitmapInfo^,BitmapBits^,256);
            if AVIStreamSetFormat(ps,0,BitmapInfo,BitmapInfoSize)=AVIERR_OK then
            begin
              for i:=0 to List.Count-1 do
                with (List.Objects[i] as TBitmap) do
                begin
                  InternalGetDIB(Handle,0,BitmapInfo^,BitmapBits^,256);
                  if AVIStreamWrite(ps,i,1,BitmapBits,BitmapSize,AVIIF_KEYFRAME,nul,nul)<>AVIERR_OK then
                  begin
                    raise Exception.Create('Could not add frame');
                    break;
                  end;
                end;
            end;
          end;
          FreeMem(BitmapInfo);
          FreeMem(BitmapBits);
        end;

      AVIStreamRelease(ps);
      AVIFileRelease(pfile);

      AVIFileExit;
end;



с использованием модулей:

Код

unit Vfw_2;

{ don't know who wrote this - the AVI section for avifil32.dll - Thanks !!!}

interface

uses Windows, IUnk;

type

{ TAVIFileInfoW record }

  LONG = Longint;
  PVOID = Pointer;

  TAVIFileInfoW = record
    dwMaxBytesPerSec,           // max. transfer rate
    dwFlags,                     // the ever-present flags
    dwCaps,
    dwStreams,
    dwSuggestedBufferSize,

    dwWidth,
    dwHeight,

    dwScale,
    dwRate,           // dwRate / dwScale == samples/second
    dwLength,

    dwEditCount: DWORD;

    szFileType: array[0..63] of WideChar;                     // descriptive string for file type?
  end;
  PAVIFileInfoW = ^TAVIFileInfoW;

{ TAVIStreamInfoA record }

  TAVIStreamInfoA = record
    fccType,
    fccHandler,
    dwFlags,        // Contains AVITF_* flags
    dwCaps: DWORD;
    wPriority,
    wLanguage: WORD;
    dwScale,
    dwRate, // dwRate / dwScale == samples/second
    dwStart,
    dwLength, // In units above...
    dwInitialFrames,
    dwSuggestedBufferSize,
    dwQuality,
    dwSampleSize: DWORD;
    rcFrame: TRect;
    dwEditCount,
    dwFormatChangeCount,
    szName:  array[0..63] of AnsiChar;
  end;
  TAVIStreamInfo = TAVIStreamInfoA;
  
{ TAVIStreamInfoW record }

  TAVIStreamInfoW = record
    fccType,
    fccHandler,
    dwFlags,        // Contains AVITF_* flags
    dwCaps: DWORD;
    wPriority,
    wLanguage: WORD;
    dwScale,
    dwRate, // dwRate / dwScale == samples/second
    dwStart,
    dwLength, // In units above...
    dwInitialFrames,
    dwSuggestedBufferSize,
    dwQuality,
    dwSampleSize: DWORD;
    rcFrame: TRect;
    dwEditCount,
    dwFormatChangeCount,
    szName:  array[0..63] of WideChar;
  end;

{ IAVIStream interface }

  IAVIStream = class(IUnknown)
    function Create(lParam1, lParam2: LPARAM): HResult; virtual; stdcall; abstract;
    function Info(var psi: TAVIStreamInfoW; lSize: LONG): HResult; virtual; stdcall; abstract;
    function FindSample(lPos, lFlags: LONG): LONG; virtual; stdcall; abstract;
    function ReadFormat(lPos: LONG; lpFormat: PVOID; var lpcbFormat: LONG): HResult; virtual; stdcall; abstract;
    function SetFormat(lPos: LONG; lpFormat: PVOID; lpcbFormat: LONG): HResult; virtual; stdcall; abstract;
    function Read(lStart, lSamples: LONG; lpBuffer: PVOID; cbBuffer: LONG; var plBytes: LONG; var plSamples: LONG): HResult; virtual; stdcall; abstract;
    function Write(lStart, lSamples: LONG; lpBuffer: PVOID; cbBuffer: LONG; dwFlags: DWORD; var plSampWritten: LONG; var plBytesWritten: LONG): HResult; virtual; stdcall; abstract;
    function Delete(lStart, lSamples: LONG): HResult; virtual; stdcall; abstract;
    function ReadData(fcc: DWORD; lp: PVOID; var lpcb: LONG): HResult; virtual; stdcall; abstract;
    function WriteData(fcc: DWORD; lp: PVOID; cb:  LONG): HResult; virtual; stdcall; abstract;
    function SetInfo(var lpInfo: TAVIStreamInfoW; cbInfo: LONG): HResult; virtual; stdcall; abstract;
  end;
  PAVIStream = ^IAVIStream;

{ IAVIFile interface }

  IAVIFile = class(IUnknown)
    function Info(var pfi: TAVIFileInfoW; lSize: LONG): HResult; virtual; stdcall; abstract;
    function GetStream(var ppStream: PAVIStream; fccType: DWORD; lParam: LONG): HResult; virtual; stdcall; abstract;
    function CreateStream(var ppStream: PAVIStream; var pfi: TAVIFileInfoW): HResult; virtual; stdcall; abstract;
    function WriteData(ckid: DWORD; lpData: PVOID; cbData: LONG): HResult; virtual; stdcall; abstract;
    function ReadData(ckid: DWORD; lpData: PVOID; var lpcbData: LONG): HResult; virtual; stdcall; abstract;
    function EndRecord: HResult; virtual; stdcall; abstract;
    function DeleteStream(fccType: DWORD; lParam: LONG): HResult; virtual; stdcall; abstract;
  end;
  PAVIFile = ^IAVIFile;

procedure AVIFileInit; stdcall;
procedure AVIFileExit; stdcall;
function AVIFileOpen(var ppfile: PAVIFile; szFile: LPCSTR; uMode: UINT; lpHandler: PCLSID): HResult; stdcall;
function AVIFileCreateStream(pfile: PAVIFile; var ppavi: PAVISTREAM; var psi: TAVIStreamInfoA): HResult; stdcall;
function AVIStreamSetFormat(pavi: PAVIStream; lPos: LONG; lpFormat: PVOID; cbFormat: LONG): HResult; stdcall;
function AVIStreamWrite(pavi: PAVIStream; lStart, lSamples: LONG; lpBuffer: PVOID; cbBuffer: LONG; dwFlags: DWORD; var plSampWritten: LONG; var plBytesWritten: LONG): HResult; stdcall;
function AVIStreamRelease(pavi: PAVISTREAM): ULONG; stdcall;
function AVIFileRelease(pfile: PAVIFile): ULONG; stdcall;

const
  AVIERR_OK      = 0;

  AVIIF_LIST      = $01;
  AVIIF_TWOCC            = $02;
  AVIIF_KEYFRAME  = $10;

  streamtypeVIDEO = $73646976; // DWORD( 'v', 'i', 'd', 's' )

{ AVI interface IDs }

  IID_IAVIFile: TGUID = (
    D1:$00020020;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46));
  IID_IAVIStream: TGUID = (
    D1:$00020021;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46));
  IID_IAVIStreaming: TGUID = (
    D1:$00020022;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46));
  IID_IGetFrame: TGUID = (
    D1:$00020023;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46));
  IID_IAVIEditStream: TGUID = (
    D1:$00020024;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46));

{ AVI class IDs }

  CLSID_AVISimpleUnMarshal: TGUID = (
    D1:$00020009;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46));
  CLSID_AVIFile: TGUID = (
    D1:$00020000;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46));

implementation

procedure AVIFileInit; stdcall; external 'avifil32.dll' name 'AVIFileInit';
procedure AVIFileExit; stdcall; external 'avifil32.dll' name 'AVIFileExit';
function AVIFileOpen(var ppfile: PAVIFILE; szFile: LPCSTR; uMode: UINT; lpHandler: PCLSID): HResult; external 'avifil32.dll' name 'AVIFileOpenA';
function AVIFileCreateStream(pfile: PAVIFile; var ppavi: PAVIStream; var psi: TAVIStreamInfoA): HResult; external 'avifil32.dll' name 'AVIFileCreateStreamA';
function AVIStreamSetFormat(pavi: PAVIStream; lPos: LONG; lpFormat: PVOID; cbFormat: LONG): HResult; external 'avifil32.dll' name 'AVIStreamSetFormat';
function AVIStreamWrite(pavi: PAVIStream; lStart, lSamples: LONG; lpBuffer: PVOID; cbBuffer: LONG; dwFlags: DWORD; var plSampWritten: LONG; var plBytesWritten: LONG): HResult; external 'avifil32.dll' name 'AVIStreamWrite';
function AVIStreamRelease(pavi: PAVIStream): ULONG; external 'avifil32.dll' name 'AVIStreamRelease';
function AVIFileRelease(pfile: PAVIFile): ULONG; external 'avifil32.dll' name 'AVIFileRelease';

end.
 

и

Код

unit DIBitmap;

interface

uses Windows, SysUtils, Classes;

procedure InitializeBitmapInfoHeader(Bitmap: HBITMAP; var BI: TBitmapInfoHeader;
  Colors: Integer);

procedure InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer;
  var ImageSize: DWORD; Colors: Integer);

function InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE;
  var BitmapInfo; var Bits; Colors: Integer): Boolean;

implementation

procedure InitializeBitmapInfoHeader(Bitmap: HBITMAP; var BI: TBitmapInfoHeader;
  Colors: Integer);
var
  BM: Windows.TBitmap;
begin
  GetObject(Bitmap, SizeOf(BM), @BM);
  with BI do
  begin
    biSize := SizeOf(BI);
    biWidth := BM.bmWidth;
    biHeight := BM.bmHeight;
    if Colors <> 0 then
      case Colors of
        2: biBitCount := 1;
        16: biBitCount := 4;
        256: biBitCount := 8;
      end
    else biBitCount := BM.bmBitsPixel * BM.bmPlanes;
    biPlanes := 1;
    biXPelsPerMeter := 0;
    biYPelsPerMeter := 0;
    if biBitCount>8 then biClrUsed := 0 else biClrUsed := Colors;
    biClrImportant := 0;
    biCompression := BI_RGB;
    if biBitCount in [16, 32] then biBitCount := 24;
    biSizeImage := (((biWidth * biBitCount) + 31) div 32) * 4 * biHeight;
  end;
end;

procedure InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer;
  var ImageSize: DWORD; Colors: Integer);
var
  BI: TBitmapInfoHeader;
begin
  InitializeBitmapInfoHeader(Bitmap, BI, Colors);
  with BI do
  begin
    case biBitCount of
      24: InfoHeaderSize := SizeOf(TBitmapInfoHeader);
    else
      InfoHeaderSize := SizeOf(TBitmapInfoHeader) + SizeOf(TRGBQuad) *
      (1 shl biBitCount);
    end;
  end;
  ImageSize := BI.biSizeImage;
end;

function InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE;
  var BitmapInfo; var Bits; Colors: Integer): Boolean;
var
  OldPal: HPALETTE;
  Focus: HWND;
  DC: HDC;
begin
  InitializeBitmapInfoHeader(Bitmap, TBitmapInfoHeader(BitmapInfo), Colors);
  OldPal := 0;
  Focus := GetFocus;
  DC := GetDC(Focus);
  try
    if Palette <> 0 then
    begin
      OldPal := SelectPalette(DC, Palette, False);
      RealizePalette(DC);
    end;
    Result := GetDIBits(DC, Bitmap, 0, TBitmapInfoHeader(BitmapInfo).biHeight, @Bits,
      TBitmapInfo(BitmapInfo), DIB_RGB_COLORS) <> 0;
  finally
    if OldPal <> 0 then SelectPalette(DC, OldPal, False);
    ReleaseDC(Focus, DC);
  end;
end;

end.


2)

Код

procedure CreateAVI(const FileName: string; IList: TStringList;
  FramesPerSec: integer);
var
  Opts: AVI_COMPRESS_OPTIONS;
  pOpts: Pointer;
  pFile, ps, psCompressed: DWORD;
  strhdr: AVI_STREAM_INFO;
  i: integer;
  BFile: file;
  m_Bih: BITMAPINFOHEADER;
  m_Bfh: BITMAPFILEHEADER;
  m_MemBits: packed array of byte;
  m_MemBitMapInfo: packed array of byte;
begin
  DeleteFile(PChar(FileName));
  Fillchar(Opts, SizeOf(Opts), 0);
  FillChar(strhdr, SizeOf(strhdr), 0);
  Opts.fccHandler := 541215044; // Full frames Uncompressed
  AVIFileInit;
  pfile := 0;
  pOpts := @Opts;

  if AVIFileOpen(@pFile, PChar(FileName), OF_WRITE or OF_CREATE, 0) = 0 then
  begin
    // Determine Bitmap Properties from file item[0] in list
    AssignFile(BFile, IList[0]);
    {$I-}
    Reset(BFile, 1);
    if IOresult = 0 then
    try
      BlockRead(BFile, m_Bfh, SizeOf(m_Bfh));
      BlockRead(BFile, m_Bih, SizeOf(m_Bih));
      SetLength(m_MemBitMapInfo, m_bfh.bfOffBits - 14);
      SetLength(m_MemBits, m_Bih.biSizeImage);
      Seek(BFile, SizeOf(m_Bfh));
      BlockRead(BFile, m_MemBitMapInfo[0], length(m_MemBitMapInfo));
    finally
      CloseFile(BFile);
    end;
    {$I+}

    strhdr.fccType := mmioStringToFOURCCA('vids', 0); // stream type video
    strhdr.fccHandler := 0; // def AVI handler
    strhdr.dwScale := 1;
    strhdr.dwRate := FramesPerSec; // fps 1 to 30
    strhdr.dwSuggestedBufferSize := m_Bih.biSizeImage; // size of 1 frame
    SetRect(strhdr.rcFrame, 0, 0, m_Bih.biWidth, m_Bih.biHeight);

    if AVIFileCreateStream(pFile, @ps, @strhdr) = 0 then
    begin
      // if you want user selection options then call following line
      // (but seems to only like "Full frames Uncompressed option)

      // AVISaveOptions(Application.Handle,
      //                ICMF_CHOOSE_KEYFRAME or ICMF_CHOOSE_DATARATE,
      //                1,@ps,@pOpts);
      // AVISaveOptionsFree(1,@pOpts);

      if AVIMakeCompressedStream(@psCompressed, ps, @opts, 0) = 0 then
      begin
        if AVIStreamSetFormat(psCompressed, 0, @m_memBitmapInfo[0],
          length(m_MemBitMapInfo)) = 0 then
        begin

          for i := 0 to IList.Count - 1 do
          begin
            AssignFile(BFile, IList[i]);
            {$I-}
            Reset(BFile, 1);
            if IOresult = 0 then
            try
              Seek(BFile, m_bfh.bfOffBits);
              BlockRead(BFile, m_MemBits[0], m_Bih.biSizeImage);
              Seek(BFile, SizeOf(m_Bfh));
              BlockRead(BFile, m_MemBitMapInfo[0], length(m_MemBitMapInfo));
            finally
              CloseFile(BFile);
            end;
            {$I+}

            if AVIStreamWrite(psCompressed, i, 1, @m_MemBits[0],
              m_Bih.biSizeImage, AVIIF_KEYFRAME, 0, 0) <> 0 then
            begin
              //ShowMessage('Error during Write AVI File');
              break;
            end;
          end;
        end;
      end;
    end;

    AVIStreamRelease(ps);
    AVIStreamRelease(psCompressed);
    AVIFileRelease(pFile);
  end;

  AVIFileExit;
  m_MemBitMapInfo := nil;
  m_memBits := nil;
end;

с использованием модуля:
Код

unit Data;

interface

uses Types;

const
  // AVISaveOptions Dialog box flags
  ICMF_CHOOSE_KEYFRAME = 1; 
  ICMF_CHOOSE_DATARATE = 2;
  ICMF_CHOOSE_PREVIEW = 4;
  ICMF_CHOOSE_ALLCOMPRESSORS = 8; 

  // can handle the input format
  // or input data
  AVIIF_KEYFRAME = 10;

type

  AVI_COMPRESS_OPTIONS = packed record
    fccType: DWORD; // stream type, for consistency
    fccHandler: DWORD; // compressor
    dwKeyFrameEvery: DWORD; // keyframe rate
    dwQuality: DWORD; // compress quality 0-10,000
    dwBytesPerSecond: DWORD; // bytes per second
    dwFlags: DWORD; // flags... see below
    lpFormat: DWORD; // save format
    cbFormat: DWORD;
    lpParms: DWORD; // compressor options
    cbParms: DWORD;
    dwInterleaveEvery: DWORD; // for non-video streams only
  end;

  AVI_STREAM_INFO = packed record
    fccType: DWORD;
    fccHandler: DWORD;
    dwFlags: DWORD;
    dwCaps: DWORD;
    wPriority: word;
    wLanguage: word;
    dwScale: DWORD;
    dwRate: DWORD;
    dwStart: DWORD;
    dwLength: DWORD;
    dwInitialFrames: DWORD;
    dwSuggestedBufferSize: DWORD;
    dwQuality: DWORD;
    dwSampleSize: DWORD;
    rcFrame: TRect;
    dwEditCount: DWORD;
    dwFormatChangeCount: DWORD;
    szName: array[0..63] of char;
  end;

  BITMAPINFOHEADER = packed record
    biSize: DWORD;
    biWidth: DWORD;
    biHeight: DWORD;
    biPlanes: word;
    biBitCount: word;
    biCompression: DWORD;
    biSizeImage: DWORD;
    biXPelsPerMeter: DWORD;
    biYPelsPerMeter: DWORD;
    biClrUsed: DWORD;
    biClrImportant: DWORD;
  end;

  BITMAPFILEHEADER = packed record
    bfType: word; //"magic cookie" - must be "BM"
    bfSize: integer;
    bfReserved1: word;
    bfReserved2: word;
    bfOffBits: integer;
  end;

  // DLL External declarations

function AVISaveOptions(Hwnd: DWORD; uiFlags: DWORD; nStreams: DWORD;
  pPavi: Pointer; plpOptions: Pointer): boolean;
  stdcall; external 'avifil32.dll';

function AVIFileCreateStream(pFile: DWORD; pPavi: Pointer; pSi: Pointer): integer;
  stdcall; external 'avifil32.dll'; 

function AVIFileOpen(pPfile: Pointer; szFile: PChar; uMode: DWORD; 
  clSid: DWORD): integer; 
  stdcall; external 'avifil32.dll';
 
function AVIMakeCompressedStream(psCompressed: Pointer; psSource: DWORD; 
  lpOptions: Pointer; pclsidHandler: DWORD): integer; 
  stdcall; external 'avifil32.dll'; 
 
function AVIStreamSetFormat(pAvi: DWORD; lPos: DWORD; lpGormat: Pointer; 
  cbFormat: DWORD): integer;
  stdcall; external 'avifil32.dll'; 
 
function AVIStreamWrite(pAvi: DWORD; lStart: DWORD; lSamples: DWORD; 
  lBuffer: Pointer; cBuffer: DWORD; dwFlags: DWORD; 
  plSampWritten: DWORD; plBytesWritten: DWORD): integer; 
  stdcall; external 'avifil32.dll'; 
 
function AVISaveOptionsFree(nStreams: DWORD; ppOptions: Pointer): integer; 
  stdcall; external 'avifil32.dll'; 

function AVIFileRelease(pFile: DWORD): integer; stdcall; external 'avifil32.dll'; 
 
procedure AVIFileInit; stdcall; external 'avifil32.dll'; 
 
procedure AVIFileExit; stdcall; external 'avifil32.dll'; 
 
function AVIStreamRelease(pAvi: DWORD): integer; stdcall; external 'avifil32.dll'; 
 
function mmioStringToFOURCCA(sz: PChar; uFlags: DWORD): integer; 
  stdcall; external 'winmm.dll';

implementation

end.


А проблема в следующем:
В первом способе видео собирается нормально, за исключением цветового набора(цвета не соответствуют картинкам).
А во втором случае, не получается собрать его 25кадр/сек(получается что-то типа анимации)
Буду признателен за любую помощь!

PM MAIL   Вверх
Predator_2004
Дата 1.2.2008, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 85
Регистрация: 26.4.2007

Репутация: нет
Всего: нет



Может есть способ сделать это с помощью DSPack?
PM MAIL   Вверх
Alexeis
Дата 1.2.2008, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 55
Всего: 459



Predator_2004, есть еще вот такой набор модулей (см. атач.)
  Для сохранения используется модуль AVICompression.


Присоединённый файл ( Кол-во скачиваний: 78 )
Присоединённый файл  avi_work.rar 26,79 Kb


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Predator_2004
Дата 2.2.2008, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 85
Регистрация: 26.4.2007

Репутация: нет
Всего: нет



Сейчас попробую...
PM MAIL   Вверх
Predator_2004
Дата 2.2.2008, 01:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 85
Регистрация: 26.4.2007

Репутация: нет
Всего: нет



Попробовал. Вроде сделал как надо, только видеофайл не открывается ни одним проигрывателем. Размер нормальный. Похоже он собирается как-то не так. Вот как я делал:
Код

var Compressor:TAVICompressor;
    Options:TAVIFileOptions;

procedure CreateAVI(FileName:string; List:TStringList);
var i:integer;
    Bmp:Graphics.TBitmap;
begin
        Compressor:=TAVICompressor.Create;
        //Options.Init;
        Compressor.Open(FileName,Options);
        for i:=0 to List.Count-1 do
        begin
          Bmp:=TBitmap.Create;
          Bmp.LoadFromFile(List.Strings[i]);
          Compressor.WriteFrame(Bmp);
          Bmp.Free;
        end;
        Compressor.Close;
        Compressor.Destroy;
end;

PM MAIL   Вверх
Alexeis
Дата 2.2.2008, 01:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 55
Всего: 459



Predator_2004, структура TAVIFileOptions попросту не заполнена, без этого он не знает параметры видео.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Predator_2004
Дата 2.2.2008, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 85
Регистрация: 26.4.2007

Репутация: нет
Всего: нет



А если раскомментировать строчку с инициализацией структуры, то код дальше не выполняется. Вылетает на открытии файла с Access violation.

Переделал. Вылезает окно сжатия файла, но после него ничего не делается. Создается файл 0 байт. Отключить окно тоже не получилось. Без него почему-то ничего не работает.

Это сообщение отредактировал(а) Predator_2004 - 2.2.2008, 12:15
PM MAIL   Вверх
Alexeis
Дата 2.2.2008, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 55
Всего: 459



Цитата(Predator_2004 @  2.2.2008,  11:02 Найти цитируемый пост)
А если раскомментировать строчку с инициализацией структуры, то код дальше не выполняется. Вылетает на открытии файла с Access violation.

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


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alexeis
Дата 2.2.2008, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 55
Всего: 459



Вот накидал пример. Я раскадрировал шрека и собрал снова. дефолтный кодек тут так себе, потому битрейт пришлось поставить по больше.

Код

procedure TForm1.Button1Click(Sender: TObject);
var
  Ops  : TAVIFileOptions;
  Cmpr : TAVICompressor;
  bmp  : TBitMap;
  i    : Integer;
  fh   : TMemoryStream;
begin
  bmp := TBitMap.Create;
  bmp.LoadFromFile('H:\temp\Frame0001.bmp'); //первый кадр
  Ops.Init;
  Ops.Width     := bmp.Width;
  Ops.Height    := bmp.Height;
  Ops.FrameRate := 25; //число кадров в сек
  Ops.ShowDialog:= false;
  Ops.KeyFrameEvery := Ops.FrameRate;
  Ops.BytesPerSecond:= 400 * 1024; //400 кб/с битрейт

  Cmpr := TAVICompressor.Create;
  Cmpr.Open('H:\temp\1.avi', Ops);

  fh   := TMemoryStream.Create;
  for I := 1 to 627
  do
    Begin
      fh.LoadFromFile(Format('%s%.4d%s', ['H:\temp\Frame', i, '.bmp']));
    //  bmp.LoadFromFile(Format('%s%.4d%s', ['H:\temp\Frame', i, '.bmp']));
      Cmpr.WriteFrame(PBitmapInfo(Pointer(Integer(fh.Memory) + sizeof(BitmapFileHeader)))); //читаем битмап напрямую, так быстрее
      memo1.Lines.Add(Format('%s%.4d%s', ['H:\temp\Frame', i, '.bmp']));
      Application.ProcessMessages;
    End;
  fh.Free;
  Cmpr.Close;
  Cmpr.Free;
  bmp.Free;
end;



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Predator_2004
Дата 7.2.2008, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 85
Регистрация: 26.4.2007

Репутация: нет
Всего: нет



Спасибо огромное! РАботает! smile 
PM MAIL   Вверх
BLACK_KOT
Дата 11.8.2008, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 305
Регистрация: 20.12.2006

Репутация: нет
Всего: -1



Alexeis ,  я несколько изменил твой пример,  собственно ничего не изменилось -
Код

procedure TForm1.Button1Click(Sender: TObject);
var
  Ops  : TAVIFileOptions;
  Cmpr : TAVICompressor;
  bmp  : TBitMap;
  i    : Integer;
begin
  bmp := TBitMap.Create;
  bmp.LoadFromFile('C:\1\0.bmp'); //ïåðâûé êàäð
  Ops.Init;
  Ops.Width     := bmp.Width;
  Ops.Height    := bmp.Height;
  Ops.FrameRate := 5; //÷èñëî êàäðîâ â ñåê
  Cmpr := TAVICompressor.Create;
  Cmpr.Open('C:\1\1.avi', Ops);
  for I := 0 to 9 do
    Begin
      bmp.LoadFromFile('C:\1\' +inttostr(i)+ '.bmp');
      Cmpr.WriteFrame(bmp);
    End;
  Cmpr.Close;
  Cmpr.Free;
  bmp.Free;
end;


но качества авишного как небыло так и нет почемуто - кадры на экране- серые полоски. больше ничего не видать.

а вот эти строки
Код

Ops.KeyFrameEvery := Ops.FrameRate;
  Ops.BytesPerSecond:= 400 * 1024; //400 кб/с битрейт

ваабще ничего не меняют.
поправь меня, если я не прав


--------------------
                       .. я - демо версия Бога от Microsoft..
PM MAIL   Вверх
Alexeis
Дата 11.8.2008, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 55
Всего: 459



BLACK_KOT, попробуй ничего не менять в моем примере. Ситуация не поменяется? В каком формате битмапки?


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
BLACK_KOT
Дата 11.8.2008, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 305
Регистрация: 20.12.2006

Репутация: нет
Всего: -1



я тока адреса бмпэшек на свои переправил:
Код

procedure TForm1.Button1Click(Sender: TObject);
var
  Ops  : TAVIFileOptions;
  Cmpr : TAVICompressor;
  bmp  : TBitMap;
  i    : Integer;
  fh   : TMemoryStream;
begin
  bmp := TBitMap.Create;
  bmp.LoadFromFile('C:\1\0.bmp'); //ïåðâûé êàäð
  Ops.Init;
  Ops.Width     := bmp.Width;
  Ops.Height    := bmp.Height;
  Ops.FrameRate := 25; //÷èñëî êàäðîâ â ñåê
  Ops.ShowDialog:= false;
  Ops.KeyFrameEvery := Ops.FrameRate;
  Ops.BytesPerSecond:= 400 * 1024;

  Cmpr := TAVICompressor.Create;
  Cmpr.Open('C:\1\1.avi', Ops);

  fh   := TMemoryStream.Create;
  for I := 0 to 9
  do
    Begin
      fh.LoadFromFile('C:\1\'+inttostr(i)+'.bmp');
      Cmpr.WriteFrame(PBitmapInfo(Pointer(Integer(fh.Memory) + sizeof(BitmapFileHeader)))); 
      memo1.Lines.Add('C:\1\'+inttostr(i)+'.bmp');
      Application.ProcessMessages;
    End;
  fh.Free;
  Cmpr.Close;
  Cmpr.Free;
  bmp.Free;
end;

тоже самое.

битмапки делаю скрином:
Код

procedure TForm1.Timer1Timer(Sender: TObject);
var
bm: TBitMap;
CI: TCursorInfo;
Icon: TIcon;
II: TIconInfo;
r: TRect;
begin
bm := TBitMap.Create;
bm.Height:=Screen.Height;
bm.Width:= Screen.Width;
BitBlt(bm.Canvas.Handle, 0, 0, Screen.Width, Screen.Height,GetDC(0), 0, 0, SRCCOPY);

if CheckBox1.Checked then
  begin
  Icon:=TIcon.Create;
  r:=Rect(0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
  CI.cbSize:=SizeOf(CI);
  if (GetCursorInfo(CI)) and (CI.flags=CURSOR_SHOWING) then
    begin
    Icon.Handle:=CopyIcon(CI.hCursor);
    if GetIconInfo(Icon.Handle,II) then
    bm.Canvas.Draw(ci.ptScreenPos.x - Integer(II.xHotspot) - r.Left, ci.ptScreenPos.y - Integer(II.yHotspot) - r.Top, Icon);
    end;
  end;

bm.SaveToFile('c:\1\'+inttostr(k)+'.bmp');
Memo1.Lines.Add('c:\1\'+inttostr(k)+'.bmp');
bm.Free;
end;



--------------------
                       .. я - демо версия Бога от Microsoft..
PM MAIL   Вверх
Nashev
Дата 4.7.2011, 03:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 6.1.2008

Репутация: нет
Всего: нет



Спасибо за тему. Я нынче занимался похожей задачей и она мне очень помогла. Пользовался модулями из вложения в этой теме.

Так, как компилировал под DelphiXE, пришлось в модуле AVIFile32.pas функциям, которые принимают PChar дописать приписки про юникодную версию, типа этой: external 'AVIFil32.dll' name 'AVIFileOpenW';

До того как я это сделал, у меня происходил AccessViolation на первом вызове Compressor.WriteFrame(Bmp), потому что перед этим вызов Compressor.Open молча падал при попытке открыть файл. Чтоб он падал не молча, я у себя его обернул в вызов процедуры CheckOSError()
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • По вопросам разработки игр стоит заглянуть сюда

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема »


 




[ Время генерации скрипта: 0.0782 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.