Ir al contenido


Foto

[RESUELTO] Generar video de una secuencia de imágenes


  • Por favor identifícate para responder
17 respuestas en este tema

#1 madiazg

madiazg

    Member

  • Miembros
  • PipPip
  • 28 mensajes

Escrito 14 diciembre 2010 - 06:33

Hola,
alguien puede orientarme sobre el asunto de referencia?
Tengo un montón de imágenes en formato jpg en una carpeta y quiero generar una secuencia de vídeo en formato avi sin compresión.

Programo en Turbodelphi por lo que no puedo/debo utilizar componentes externos.

Saludos...
Miguel Angel
  • 0

#2 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 14 diciembre 2010 - 07:58

http://www.delphiacc...hp?topic=3990.0

Saludos.
  • 0

#3 madiazg

madiazg

    Member

  • Miembros
  • PipPip
  • 28 mensajes

Escrito 14 diciembre 2010 - 10:44

Hola,
lo que yo quiero conseguir es lo que falta en dicho hilo (seoane lo realiza con virtualdub), o sea, generar el AVI.
Saludos...
Miguel Angel
  • 0

#4 cHackAll

cHackAll

    Advanced Member

  • Moderador
  • PipPipPip
  • 598 mensajes

Escrito 14 diciembre 2010 - 05:26



delphi
  1. program jpg2avi; // by cHackAll
  2.  
  3. uses Windows;
  4.  
  5. function GdiplusStartup(var hToken: Cardinal; Startup, Output: PChar): Cardinal; stdcall external 'gdiplus';
  6. function GdipLoadImageFromFile(lpFileName: PWChar; var hImage: Cardinal): Cardinal; stdcall external 'gdiplus';
  7. function GdipCreateBitmapFromFile(lpFileName: PWChar; var hBitmap: Cardinal): Cardinal; stdcall external 'gdiplus';
  8. function GdipCreateFromHDC(hCanvas: Cardinal; var hGraphics: Cardinal): Cardinal; stdcall external 'gdiplus';
  9. function GdipDrawImageRectI(hGraphics, hImage, X, Y, Width, Height: Cardinal): Cardinal; stdcall external 'gdiplus';
  10. function GdipDeleteGraphics(hGraphics: Cardinal): Cardinal; stdcall external 'gdiplus';
  11. function GdipDisposeImage(hImage: Cardinal): Cardinal; stdcall external 'gdiplus';
  12. procedure GdiplusShutdown(hToken: Cardinal); stdcall external 'gdiplus';
  13.  
  14. procedure AVIFileInit; stdcall external 'avifil32';
  15. function AVIFileOpen(var hFile: Cardinal; lpFileName: PChar; uMode, clsid: Cardinal): Cardinal; stdcall external 'avifil32';
  16. function AVIFileCreateStream(hFile: Cardinal; var hAvi: Cardinal; var StreamInfo): Cardinal; stdcall external 'avifil32';
  17. function AVIMakeCompressedStream(var hStream: Cardinal; hSource: Cardinal; var Options; pclsidHandler: Cardinal): Cardinal; stdcall external 'avifil32';
  18. function AVIStreamSetFormat(hAvi, lPos: Cardinal; lpFormat: Pointer; cbFormat: Cardinal): Cardinal; stdcall external 'avifil32';
  19. function AVIStreamWrite(hAvi, lStart, lSamples: Cardinal; lBuffer: PChar; cBuffer, dwFlags, plSampWritten, plBytesWritten: Cardinal): Cardinal; stdcall external 'avifil32';
  20. function AVIStreamRelease(hStream: Cardinal): Cardinal; stdcall external 'avifil32';
  21. function AVIFileRelease(hFile: Cardinal): Cardinal; stdcall external 'avifil32';
  22. procedure AVIFileExit; stdcall external 'avifil32';
  23.  
  24. var
  25. hFindFile, hToken, hBuffer, hScreen, hBitmap, hCanvas, hFile, hAvi, hStream, Index, hImage, hGraphics: Cardinal;
  26. FindFileData: TWin32FindDataW;
  27. BitmapInfo: TBitmapInfo;
  28.  
  29. Options: packed record
  30.   fccType, fccHandler,
  31.   dwKeyFrameEvery,
  32.   dwQuality,
  33.   dwBytesPerSecond,
  34.   dwFlags,
  35.   lpFormat, cbFormat,
  36.   lpParms, cbParms,
  37.   dwInterleaveEvery: Cardinal;
  38. end;
  39.  
  40. StreamInfo: packed record
  41.   fccType, fccHandler,
  42.   dwFlags, dwCaps: Cardinal;
  43.   wPriority, wLanguage: Word;
  44.   dwScale, dwRate,
  45.   dwStart, dwLength,
  46.   dwInitialFrames,
  47.   dwSuggestedBufferSize,
  48.   dwQuality, dwSampleSize: Cardinal;
  49.   rcFrame: TRect;
  50.   dwEditCount,
  51.   dwFormatChangeCount: Cardinal;
  52.   szName: array [0..63] of Char;
  53. end;
  54.  
  55. begin
  56. if GdiplusStartup(hToken, #1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0, nil) <> 0 then Exit;
  57.  
  58. hFindFile := FindFirstFileW('*.jpeg', FindFileData); //
  59. if hFindFile <> INVALID_HANDLE_VALUE then
  60.   begin
  61.   with BitmapInfo.bmiHeader do
  62.     begin
  63.     biSize := SizeOf(BitmapInfo.bmiHeader);
  64.     biWidth := 1280;                        //
  65.     biHeight := 720;                        //
  66.     biPlanes := 1;
  67.     biBitCount := 24;
  68.     biCompression := BI_RGB;
  69.     biSizeImage := biWidth * biBitCount div 8;
  70.     Index := biSizeImage mod 4;
  71.  
  72.     if Index <> 0 then
  73.       Inc(biSizeImage, 4 - Index);
  74.     biSizeImage := biSizeImage * Cardinal(biHeight);
  75.     hBuffer := LocalAlloc(LMEM_ZEROINIT, biSizeImage);
  76.     end;
  77.   hScreen := GetDC(0);
  78.   hBitmap := CreateDIBitmap(hScreen, BitmapInfo.bmiHeader, 0, nil, BitmapInfo, DIB_RGB_COLORS);
  79.   hCanvas := CreateCompatibleDC(0);
  80.   SelectObject(hCanvas, hBitmap);
  81.   ReleaseDC(0, hScreen);
  82.  
  83.   GdipCreateFromHDC(hCanvas, hGraphics);
  84.  
  85.   Options.fccHandler := PCardinal(PChar('DIB '))^;
  86.   StreamInfo.fccType := PCardinal(PChar('vids'))^;
  87.   StreamInfo.dwScale := 1;
  88.   StreamInfo.dwRate := 1;
  89.   StreamInfo.dwSuggestedBufferSize := BitmapInfo.bmiHeader.biSizeImage;
  90.  
  91.   AVIFileInit;
  92.   if AVIFileOpen(hFile,  'movie.avi', OF_WRITE or OF_CREATE, 0) <> 0 then Exit; //
  93.   AVIFileCreateStream(hFile, hAvi, StreamInfo);
  94.   AVIMakeCompressedStream(hStream, hAvi, Options, 0);
  95.   AVIStreamSetFormat(hStream, 0, @BitmapInfo, SizeOf(BitmapInfo));
  96.  
  97.   Index := 0;
  98.   repeat
  99.     if GdipLoadImageFromFile(@FindFileData.cFileName, hImage) = 0 then
  100.     begin
  101.       with BitmapInfo.bmiHeader do
  102.       GdipDrawImageRectI(hGraphics, hImage, 0, 0, biWidth, biHeight);
  103.       GdipDisposeImage(hImage);
  104.  
  105.       GetDIBits(hCanvas, hBitmap, 0, BitmapInfo.bmiHeader.biHeight, Ptr(hBuffer), BitmapInfo, DIB_RGB_COLORS);
  106.       AVIStreamWrite(hStream, Index, 1, Ptr(hBuffer), BitmapInfo.bmiHeader.biSizeImage, 10{AVIIF_KEYFRAME}, 0, 0);
  107.     end;
  108.     Inc(Index);
  109.   until not FindNextFileW(hFindFile, FindFileData);
  110.   AVIStreamRelease(hStream);
  111.   AVIStreamRelease(hAvi);
  112.   AVIFileRelease(hFile);
  113.   AVIFileExit;
  114.  
  115.   GdipDeleteGraphics(hGraphics);
  116.   DeleteObject(hCanvas);
  117.   DeleteObject(hBitmap);
  118.  
  119.   LocalFree(hBuffer);
  120.   FindClose(hFindFile);
  121.   end;
  122. GdiplusShutdown(hToken);
  123. end.


  • 0

#5 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.991 mensajes
  • LocationMadrid - España

Escrito 14 diciembre 2010 - 05:34

(y)

Saludos.
  • 0

#6 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.242 mensajes
  • LocationMéxico

Escrito 14 diciembre 2010 - 10:52

¡Caramba little bro!

Siempre con code genial (y)

Salud OS


  • 0

#7 seoane

seoane

    Advanced Member

  • Moderador
  • PipPipPip
  • 1.257 mensajes
  • LocationEspaña

Escrito 15 diciembre 2010 - 02:06

Excelente!!! :D
  • 0

#8 madiazg

madiazg

    Member

  • Miembros
  • PipPip
  • 28 mensajes

Escrito 16 diciembre 2010 - 02:27

Hola,me da un error en la siguiente línea:


delphi
  1.   FindClose(hFindFile);


[Pascal Error] jpgtoavi.pas(151): E2033 Types of actual and formal var parameters must be identical
¿A qué puede ser debido?
Saludos...Miguel Angel
  • 0

#9 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.242 mensajes
  • LocationMéxico

Escrito 16 diciembre 2010 - 03:37

Hola madiazg.

El problema es que estas intentando hacerlo en una unidad .pas, este código es todo el programa y está en el archivo dpr. (sello característico de cHackAll :))

Salud OS

Tip: Copia el código y guardalo en un archivo de texto, renombra el archivo como jpg2avi.dpr y lo abres con tu Delphi, compilas y ya está.


  • 0

#10 madiazg

madiazg

    Member

  • Miembros
  • PipPip
  • 28 mensajes

Escrito 17 diciembre 2010 - 09:11

Hola,
disculpen mi ignorancia. Lo que yo deseo es integrar el código en mi programa. ¿cómo he de hacerlo?
Saludos...Miguel Angel
  • 0

#11 madiazg

madiazg

    Member

  • Miembros
  • PipPip
  • 28 mensajes

Escrito 19 diciembre 2010 - 09:42

Hola,no consigo 'descifrar' el código de cHackAll.Cada día descubro que mi nivel de delphi es más bajo.¿Alguien puede ayudarme a probar el código en mi programa?
Saludos...Miguel Angel
  • 0

#12 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.242 mensajes
  • LocationMéxico

Escrito 19 diciembre 2010 - 10:07

Hola madiazg

Sólo cambia ésta línea:



delphi
  1.   FindClose(hFindFile);



por ésta:



delphi
  1.   windows.FindClose(hFindFile);



La función que se requiere es parte de la unidad Windows (como te lo está indicando al inicio, sólo está utilizando en el uses windows) lo que hace delphi es asumir que está queriendo utilizar la rutina FindClose() que está en la unidad SysUtils por lo que te manda un error de tipo.

Salud OS

  • 0

#13 madiazg

madiazg

    Member

  • Miembros
  • PipPip
  • 28 mensajes

Escrito 19 diciembre 2010 - 11:20

Hola,gracias por ayudarme.Efectivamente, al incluir 'windows.' ya no se produce el error.
Tengo dudas de cómo funciona este programa. He compilado el código y me ha generado un fichero denomidado jpgtoavi.exe. He copiado dicho código en una carpeta con varias imágenes jpg y he ejecutado el programa pero no produce ningún avi. ¿Hay que introducir algún tipo de parámetro?La verdad es que no consigo entender el código propuesto por chackall.
Saludos...Miguel Angel
  • 0

#14 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.242 mensajes
  • LocationMéxico

Escrito 19 diciembre 2010 - 11:39

Hola

¿ Con que tipo de archivo estás queriendo generar tu video ?

El código está buscando archivos jpeg,
 


delphi
  1. hFindFile := FindFirstFileW('*.jpeg', FindFileData); //

Debes de modificar el tipo de archivo que deseas.
 


delphi
  1. hFindFile := FindFirstFileW('*.jpg', FindFileData); //
  2.  
  3. hFindFile := FindFirstFileW('*.bmp', FindFileData); //
  4.  
  5. hFindFile := FindFirstFileW('*.gif', FindFileData); //

Salud OS

 


  • 0

#15 madiazg

madiazg

    Member

  • Miembros
  • PipPip
  • 28 mensajes

Escrito 20 diciembre 2010 - 04:41

Hola,
efectivamente, el problema era que buscaba ficheros *.jpeg y la extensión de los ficheros es *.jpg. Ya funciona correctamente y lo he podido integrar en mi programa.
He publicado un par de vídeos del pequeño proyecto en el que estoy embarcado en estos momentos y que, a partir de ahora, también podré generar los AVI sin utilizar otros programas:

http://webcamtimelapse.blogspot.com/

Nuevamente, muchas gracias.
Saludos...
Miguel Angel
  • 0

#16 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.242 mensajes
  • LocationMéxico

Escrito 20 diciembre 2010 - 05:27

Pues que bien, está muy interesante tu proyecto.

Salud OS

PD, ponemos el hilo como resuelto.
  • 0

#17 felipe

felipe

    Advanced Member

  • Moderador
  • PipPipPip
  • 3.283 mensajes
  • LocationColombia

Escrito 21 diciembre 2010 - 07:18

¿PhotoLapse es el programa que usabas y la idea es usar tu propia creación?


Saludos!
  • 0

#18 madiazg

madiazg

    Member

  • Miembros
  • PipPip
  • 28 mensajes

Escrito 21 diciembre 2010 - 03:38

Efectivamente, y con el código de chackall y la ayuda de egostar el próximo Time Lapse que monté utilizaré mi propio programa para generar el AVI que posteriormente editaré con Vegas.
Saludos...Miguel Angel
  • 0