
[RESUELTO] Generar video de una secuencia de imágenes
#1
Posted 14 December 2010 - 06:33 AM
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
#3
Posted 14 December 2010 - 10:44 AM
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
#4
Posted 14 December 2010 - 05:26 PM
program jpg2avi; // by cHackAll uses Windows; function GdiplusStartup(var hToken: Cardinal; Startup, Output: PChar): Cardinal; stdcall external 'gdiplus'; function GdipLoadImageFromFile(lpFileName: PWChar; var hImage: Cardinal): Cardinal; stdcall external 'gdiplus'; function GdipCreateBitmapFromFile(lpFileName: PWChar; var hBitmap: Cardinal): Cardinal; stdcall external 'gdiplus'; function GdipCreateFromHDC(hCanvas: Cardinal; var hGraphics: Cardinal): Cardinal; stdcall external 'gdiplus'; function GdipDrawImageRectI(hGraphics, hImage, X, Y, Width, Height: Cardinal): Cardinal; stdcall external 'gdiplus'; function GdipDeleteGraphics(hGraphics: Cardinal): Cardinal; stdcall external 'gdiplus'; function GdipDisposeImage(hImage: Cardinal): Cardinal; stdcall external 'gdiplus'; procedure GdiplusShutdown(hToken: Cardinal); stdcall external 'gdiplus'; procedure AVIFileInit; stdcall external 'avifil32'; function AVIFileOpen(var hFile: Cardinal; lpFileName: PChar; uMode, clsid: Cardinal): Cardinal; stdcall external 'avifil32'; function AVIFileCreateStream(hFile: Cardinal; var hAvi: Cardinal; var StreamInfo): Cardinal; stdcall external 'avifil32'; function AVIMakeCompressedStream(var hStream: Cardinal; hSource: Cardinal; var Options; pclsidHandler: Cardinal): Cardinal; stdcall external 'avifil32'; function AVIStreamSetFormat(hAvi, lPos: Cardinal; lpFormat: Pointer; cbFormat: Cardinal): Cardinal; stdcall external 'avifil32'; function AVIStreamWrite(hAvi, lStart, lSamples: Cardinal; lBuffer: PChar; cBuffer, dwFlags, plSampWritten, plBytesWritten: Cardinal): Cardinal; stdcall external 'avifil32'; function AVIStreamRelease(hStream: Cardinal): Cardinal; stdcall external 'avifil32'; function AVIFileRelease(hFile: Cardinal): Cardinal; stdcall external 'avifil32'; procedure AVIFileExit; stdcall external 'avifil32'; var hFindFile, hToken, hBuffer, hScreen, hBitmap, hCanvas, hFile, hAvi, hStream, Index, hImage, hGraphics: Cardinal; FindFileData: TWin32FindDataW; BitmapInfo: TBitmapInfo; Options: packed record fccType, fccHandler, dwKeyFrameEvery, dwQuality, dwBytesPerSecond, dwFlags, lpFormat, cbFormat, lpParms, cbParms, dwInterleaveEvery: Cardinal; end; StreamInfo: packed record fccType, fccHandler, dwFlags, dwCaps: Cardinal; wPriority, wLanguage: Word; dwScale, dwRate, dwStart, dwLength, dwInitialFrames, dwSuggestedBufferSize, dwQuality, dwSampleSize: Cardinal; rcFrame: TRect; dwEditCount, dwFormatChangeCount: Cardinal; szName: array [0..63] of Char; end; begin if GdiplusStartup(hToken, #1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0, nil) <> 0 then Exit; hFindFile := FindFirstFileW('*.jpeg', FindFileData); // if hFindFile <> INVALID_HANDLE_VALUE then begin with BitmapInfo.bmiHeader do begin biSize := SizeOf(BitmapInfo.bmiHeader); biWidth := 1280; // biHeight := 720; // biPlanes := 1; biBitCount := 24; biCompression := BI_RGB; biSizeImage := biWidth * biBitCount div 8; Index := biSizeImage mod 4; if Index <> 0 then Inc(biSizeImage, 4 - Index); biSizeImage := biSizeImage * Cardinal(biHeight); hBuffer := LocalAlloc(LMEM_ZEROINIT, biSizeImage); end; hScreen := GetDC(0); hBitmap := CreateDIBitmap(hScreen, BitmapInfo.bmiHeader, 0, nil, BitmapInfo, DIB_RGB_COLORS); hCanvas := CreateCompatibleDC(0); SelectObject(hCanvas, hBitmap); ReleaseDC(0, hScreen); GdipCreateFromHDC(hCanvas, hGraphics); Options.fccHandler := PCardinal(PChar('DIB '))^; StreamInfo.fccType := PCardinal(PChar('vids'))^; StreamInfo.dwScale := 1; StreamInfo.dwRate := 1; StreamInfo.dwSuggestedBufferSize := BitmapInfo.bmiHeader.biSizeImage; AVIFileInit; if AVIFileOpen(hFile, 'movie.avi', OF_WRITE or OF_CREATE, 0) <> 0 then Exit; // AVIFileCreateStream(hFile, hAvi, StreamInfo); AVIMakeCompressedStream(hStream, hAvi, Options, 0); AVIStreamSetFormat(hStream, 0, @BitmapInfo, SizeOf(BitmapInfo)); Index := 0; repeat if GdipLoadImageFromFile(@FindFileData.cFileName, hImage) = 0 then begin with BitmapInfo.bmiHeader do GdipDrawImageRectI(hGraphics, hImage, 0, 0, biWidth, biHeight); GdipDisposeImage(hImage); GetDIBits(hCanvas, hBitmap, 0, BitmapInfo.bmiHeader.biHeight, Ptr(hBuffer), BitmapInfo, DIB_RGB_COLORS); AVIStreamWrite(hStream, Index, 1, Ptr(hBuffer), BitmapInfo.bmiHeader.biSizeImage, 10{AVIIF_KEYFRAME}, 0, 0); end; Inc(Index); until not FindNextFileW(hFindFile, FindFileData); AVIStreamRelease(hStream); AVIStreamRelease(hAvi); AVIFileRelease(hFile); AVIFileExit; GdipDeleteGraphics(hGraphics); DeleteObject(hCanvas); DeleteObject(hBitmap); LocalFree(hBuffer); FindClose(hFindFile); end; GdiplusShutdown(hToken); end.
#5
Posted 14 December 2010 - 05:34 PM

Saludos.
#6
Posted 14 December 2010 - 10:52 PM
Siempre con code genial

Salud OS
#7
Posted 15 December 2010 - 02:06 AM

#8
Posted 16 December 2010 - 02:27 PM
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
#9
Posted 16 December 2010 - 03:37 PM
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á.
#10
Posted 17 December 2010 - 09:11 AM
disculpen mi ignorancia. Lo que yo deseo es integrar el código en mi programa. ¿cómo he de hacerlo?
Saludos...Miguel Angel
#11
Posted 19 December 2010 - 09:42 AM
Saludos...Miguel Angel
#12
Posted 19 December 2010 - 10:07 AM
Sólo cambia ésta línea:
FindClose(hFindFile);
por ésta:
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
#13
Posted 19 December 2010 - 11:20 AM
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
#14
Posted 19 December 2010 - 11:39 AM
Hola
¿ Con que tipo de archivo estás queriendo generar tu video ?
El código está buscando archivos jpeg,
hFindFile := FindFirstFileW('*.jpeg', FindFileData); //
Debes de modificar el tipo de archivo que deseas.
hFindFile := FindFirstFileW('*.jpg', FindFileData); // hFindFile := FindFirstFileW('*.bmp', FindFileData); // hFindFile := FindFirstFileW('*.gif', FindFileData); //
Salud OS
#15
Posted 20 December 2010 - 04:41 PM
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
#16
Posted 20 December 2010 - 05:27 PM
Salud OS
PD, ponemos el hilo como resuelto.
#17
Posted 21 December 2010 - 07:18 AM
Saludos!
#18
Posted 21 December 2010 - 03:38 PM
Saludos...Miguel Angel