Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Gráficos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 22-10-2003
etruel etruel is offline
Registrado
 
Registrado: oct 2003
Posts: 5
Poder: 0
etruel Va por buen camino
acceder a frames de Divx

Hola.
Antes que nada, ME doy la bienvenida en esta magnifica Comunidad de Programadores. Y espero no meter la pata en mi primer post.

He buscado muchisimo por la web y no encontre nada que me lo solucione. Hay multitud de ejemplos, pero andan solo con avi comunes, no con Divx.

Lo que quiero hacer es acceder frame x frame a un Divx y mandarlo a un TBitmap, sin necesidad de reproducirlo.
Esto es para recorrer el video de forma mas rapida que en tiempo real.

Pongo un codigo que "casi" anduvo:
(usando vfw.pas)
Cita:
AVIFileInit;
// The AVIFileOpen function opens an AVI file
Error := AVIFileOpen(pFile, PChar(FileName), 0, nil);
...
// AVIFileInfo obtains information about an AVI file

if AVIFileInfo(pFile, @AVIINFO, SizeOf(AVIINFO)) <> AVIERR_OK then
...
MediaWidth := AVIINFO.dwWidth;
MediaHeight:= AVIINFO.dwHeight;
MediaFrames:= AVIINFO.dwLength;
MediaScale := AVIINFO.dwScale;

// Open a Stream from the file
Error := AVIFileGetStream(pFile, AVIStream, streamtypeVIDEO, 0);
...
// Prepares to decompress video frames
gapgf := AVIStreamGetFrameOpen(AVIStream, nil);
...
// Read current Frame
// AVIStreamGetFrame Returns the address of a decompressed video frame
lpbi := AVIStreamGetFrame(gapgf, iFrameNum);
...

TmpBmp := TBitmap.Create;
try
TmpBmp.Height := lpbi.biHeight;
TmpBmp.Width := lpbi.biWidth;
bits := Pointer(Integer(lpbi) + SizeOf(TBITMAPINFOHEADER));

DC_Handle := CreateDC('Display', nil, nil, nil);
try
hBmp := CreateDIBitmap(DC_Handle, // handle of device context
lpbi^, // address of bitmap size and format data
CBM_INIT, // initialization flag
bits, // address of initialization data
PBITMAPINFO(lpbi)^, // address of bitmap color-format data
DIB_RGB_COLORS); // color-data usage
finally
DeleteDC(DC_Handle);
end;
TmpBmp.Handle := hBmp;
finally
TmpBmp.Free;
end;
Esto me anda para AVIs comunes pero para videos Divx la linea
gapgf := AVIStreamGetFrameOpen(AVIStream, nil); siempre me devuelve nil, entoces falla el getframe.

Probe tambien el TmediaPlayer y no me reproduce divx.
y probé el DSPack con directshow pero no se como acceder a los frames sin tener que reproducir el video.

¿Alguien me puede dar una mano con esto?
Gracias
Responder Con Cita
  #2  
Antiguo 24-10-2003
etruel etruel is offline
Registrado
 
Registrado: oct 2003
Posts: 5
Poder: 0
etruel Va por buen camino
¿Ni siquiera un post de bienvenida?
Bueno, ya lo solucioné.
Gracias a los 4 que por lo menos leyeron el post.
Saludos
Responder Con Cita
  #3  
Antiguo 24-10-2003
Avatar de SnaKe
SnaKe SnaKe is offline
Miembro
 
Registrado: may 2003
Ubicación: Madrid (España)
Posts: 227
Poder: 22
SnaKe Va por buen camino
Hola Etruel,

Antes que nada bienvenido... yo fui uno de los que leyó tu post y no te contesté porque no tenía ni idea, tampoco me fijé que erá tu primer post...

Bueno, me gustaría saber como lo resolviste, la verdad es que me parece muy interesante el tema. Puede poner un mensaje poniendo que componentes y código has utilizado??

Gracias y un saludo.
__________________
Todos somos aficionados. La vida es tan corta que no da para más.
Guia de Estilos
Responder Con Cita
  #4  
Antiguo 24-10-2003
etruel etruel is offline
Registrado
 
Registrado: oct 2003
Posts: 5
Poder: 0
etruel Va por buen camino
pero como no!! aca esta el código
Use el Media Detector del Direct Show9. Que aunque creo que no permite acceder frame x frame, pude acceder a segundo x segundo que igual me sirve.


Cita:
var
Res: HRESULT;
bmih: tagBITMAPINFOHEADER;
hdcDest: HDC;
bmi: tagBITMAPINFO;
Bitmap: HBITMAP;
Size: Integer;
Buffer: array of PChar;
cantstream, actualstream: Integer;
Player: IMediaDet;

Begin
CoCreateInstance(CLSID_MediaDet,nil,CLSCTX_INPROC_SERVER,IID_IMediaDet,Player);
Player.put_Filename(Filename);
Player.get_OutputStreams(CantStream);
Res := Player.GetBitmapBits(ActualSeg, @Size, 0, MediaWidth, MediaHeight);
if Res = S_OK then
begin
SetLength(Buffer, Size);
hdcDest := GetDC(0);

Res := Player.GetBitmapBits(ActualSeg, 0, @Buffer[0], MediaWidth, MediaHeight);

ZeroMemory(@bmi, SizeOf(tagBITMAPINFO));

CopyMemory(@bmih, @Buffer[0], SizeOf(tagBITMAPINFOHEADER));

CopyMemory(@bmi.bmiHeader, @bmih, SizeOf(tagBITMAPINFOHEADER));

Bitmap := CreateDIBitmap(hdcDest, bmih, CBM_INIT, @Buffer[SizeOf(tagBITMAPINFOHEADER)], bmi, DIB_RGB_COLORS);

image1.Picture.Bitmap.Handle := Bitmap;

end;
end;
Responder Con Cita
  #5  
Antiguo 24-10-2003
etruel etruel is offline
Registrado
 
Registrado: oct 2003
Posts: 5
Poder: 0
etruel Va por buen camino
Otras Preguntas Mas Sencillas
Lo que quiero es poder trabajar con la imagen extraida antes de mostrarla.

Si en vez de hacer esto:
image1.Picture.Bitmap.Handle := Bitmap;

Hago esto:
image1.Picture.Bitmap.Canvas.Handle := Bitmap;

Las preguntas son:
¿Como accedo a los pixels de la imagen extraida en el canvas?
¿Como muestro el canvas luego en image1?

Por ahora se me ocurrió esto. No se si estoy bien orientado.
Si alguien sabe una forma mejor por favor que lo postee
Gracias

Última edición por etruel fecha: 24-10-2003 a las 16:46:00.
Responder Con Cita
  #6  
Antiguo 27-10-2003
Avatar de SnaKe
SnaKe SnaKe is offline
Miembro
 
Registrado: may 2003
Ubicación: Madrid (España)
Posts: 227
Poder: 22
SnaKe Va por buen camino
Hola Etruel,

Lo primero gracias por mostrarnos la solución pero me queda una duda, cuando dices que usas el Media Detector del Direct Show 9 das a entender de que ¿para que ese código funcione es necesario tener DirectX 9 ? igual acabo de preguntar una barbaridad...

Otra cosa, referente a las cuestiones en el mensaje de después del código...

Por que no haces algo así:

Código:
var
........
........
Bitmp : TBitmap;
begin
...................... // Tu código pero no asignes al TImage
...................... // sino que haz esto:

Bitmp := TBitmap.Create;
Bitmp.Handle := Bitmap;

// Ahora pintas en el canvas de Bitmp

// Bitmp.Canvas.xxxxxxxxxx

// Y una vez que hayas terminado de pintar se lo asocias al image

Image1.Picture.Bitmap.Assign(Bitmp);
No se si te servirá....

Salu2.
__________________
Todos somos aficionados. La vida es tan corta que no da para más.
Guia de Estilos
Responder Con Cita
  #7  
Antiguo 27-10-2003
etruel etruel is offline
Registrado
 
Registrado: oct 2003
Posts: 5
Poder: 0
etruel Va por buen camino
Snake:
En mi equipo tengo instalado el directx 9 no se si andará en otras versiones una vez compilado.
Use las librerias de DirectX para delphi que hay en http://www.progdigy.com.
En esos foros encontre un codigo similar al que usé yo (es decir, me basé en ese código )

Gracias por el código del canvas, algo así habia pensado; aunque sigo buscando una forma mas rapida porque tengo que acceder a cada pixel de la imagen y modificar el color uno por uno.

Saludos
PD: No tengo mucha experiencia en delphi, voy buscando información acerca de lo que quiero hacer.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 12:38:00.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi