Ir al contenido


Foto

Crear "slideshows" a partir de imagenes


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

#1 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 10 octubre 2010 - 12:58

Hace algún tiempo me pidió un amigo que le hiciera un dvd con algunas fotos de sus productos, el típico "slideshow" para poner en una televisión y que los clientes le echen un vistazo. Lo normal hubiera sido usar uno de los mil programas que hay para hacer esto en le mercado, en los que solo tienes que agregar las fotos y ya te graban el dvd con su menú y todo. Pero como ya sabéis a veces me gusta matar moscas a cañonazos, y como ningún programa terminaba de darme el resultado que buscaba, y estaba con mucho tiempo libre :D me decidí por crear mi propio programa.

Por supuesto que no me metí a crear el archivo de vídeo directamente, eso seria demasiado trabajo, lo que pensé fue en generar uno a uno los diferentes frames del vídeo y que luego otro programa, virtualdub por ejemplo, se encargara de ensamblarlos en un solo archivo de vídeo.

Luego le añadí unos cuantos efectos y transiciones, y el resultado es esto:


delphi
  1. program make;
  2.  
  3. {$APPTYPE CONSOLE}
  4.  
  5. uses Windows, SysUtils, Classes, Graphics, Jpeg, ShellApi;
  6.  
  7. type
  8.   Triplet = array[1..3]of Byte;
  9.  
  10. const
  11.   // El tamaño adecuado para un dvd
  12.   FrameHeight = 576;
  13.   FrameWidth = 720;
  14.  
  15. var
  16.   AppPath: string;
  17.   ImgList: TStringList;
  18.   LastFrame: TBitmap;
  19.   FixedFrame: TBitmap;
  20.   ShowFixedFrame: Boolean;
  21.   Index: Cardinal;
  22.   FrameSize: Cardinal;
  23.  
  24. function IndexToStr(Index: Cardinal): string;
  25. begin
  26.   Result:= IntToStr(Index);
  27.   while Length(Result) < 8 do
  28.     Result:= &#39;0&#39; + Result;
  29.   Result:= AppPath + &#39;seq\&#39; + Result + &#39;.bmp&#39;;
  30. end;
  31.  
  32. // Transicion entre dos imagenes
  33. procedure Fade(Bitmap1, Bitmap2: TBitmap; Step: Integer; Transparent: Boolean);
  34. var
  35.   P1, P2: ^Triplet;
  36.   i, j: Integer;
  37. begin
  38.   for j:= 0 to  Bitmap1.Height - 1 do
  39.   begin
  40.     P1:= Bitmap1.ScanLine[j];
  41.     P2:= Bitmap2.ScanLine[j];
  42.     for i:= 0 to Bitmap1.Width - 1 do
  43.     begin
  44.       if not (Transparent and (P2^[1] = $FF)) then
  45.       begin
  46.         inc(P1^[1], Byte(((P2^[1] - P1^[1]) *  Step) shr 6));
  47.         inc(P1^[2], Byte(((P2^[2] - P1^[2]) *  Step) shr 6));
  48.         inc(P1^[3], Byte(((P2^[3] - P1^[3]) *  Step) shr 6));
  49.       end;
  50.       inc(P1); inc(P2);
  51.     end;
  52.   end;
  53. end;
  54.  
  55. // Escribe el frame a disco, si tenemos una libreria para crear AVIs podriamos
  56. // enviar le frame directamente sin pasar por el disco.
  57. procedure WriteFrame(Bitmap: TBitmap);
  58. begin
  59.   Write(Format(&#39;%sFrames=%d Tamaño=%d Kb&#39;,[#13,Index, (Index + 1) * (FrameSize shr 10)]));
  60.   if ShowFixedFrame then
  61.     Fade(Bitmap, FixedFrame, 64, TRUE);
  62.   Bitmap.SaveToFile(IndexToStr(Index));
  63.   inc(Index);
  64. end;
  65.  
  66. function GetFrameSize: Cardinal;
  67. var
  68.   Mem: TMemoryStream;
  69. begin
  70.   Mem:= TMemoryStream.Create;
  71.   try
  72.     LastFrame.SaveToStream(Mem);
  73.     Result:= Mem.Size;
  74.   finally
  75.     Mem.Free;
  76.   end;
  77. end;
  78.  
  79. // Inicializa el ultimo frame
  80. procedure InitLastFrame(Color: TColor);
  81. begin
  82.   with LastFrame do
  83.   begin
  84.     PixelFormat:= pf24bit;
  85.     Width:= FrameWidth;
  86.     Height:= FrameHeight;
  87.     Canvas.Brush.Color:= Color;
  88.     Canvas.FillRect(Canvas.ClipRect);
  89.   end;
  90. end;
  91.  
  92. // Hace una transcion a un color (Ej: un fundido a negro)
  93. procedure FadeLastFrame(Color: TColor; Step: Integer);
  94. var
  95.   P: ^Triplet;
  96.   i, j, k: Integer;
  97.   R,G,B: Byte;
  98.   Bitmap: TBitmap;
  99. begin
  100.   R:= GetRValue(Color);
  101.   G:= GetGValue(Color);
  102.   B:= GetBValue(Color);
  103.   Bitmap:= TBitmap.Create;
  104.   try
  105.     Bitmap.Assign(LastFrame);
  106.     for k:= 1 to Step do
  107.     begin
  108.       LastFrame.Assign(Bitmap);
  109.       for j:= 0 to  LastFrame.Height - 1 do
  110.       begin
  111.         P:= LastFrame.ScanLine[j];
  112.         for i:= 0 to LastFrame.Width - 1 do
  113.         begin
  114.           inc(P^[1], Byte((( R - P^[1]) *  k) shr 6));
  115.           inc(P^[2], Byte((( G - P^[2]) *  k) shr 6));
  116.           inc(P^[3], Byte((( B - P^[3]) *  k) shr 6));
  117.           inc(P);
  118.         end;
  119.       end;
  120.       WriteFrame(LastFrame);
  121.     end;
  122.   finally
  123.     Bitmap.Free;
  124.   end;
  125. end;
  126.  
  127. // Carga un fichero en un bitmap
  128. procedure FileToBitmap(Bitmap: TBitmap; Filename: string);
  129. var
  130.   Image: TPicture;
  131. begin
  132.   Image:= TPicture.Create;
  133.   try
  134.     Image.LoadFromFile(Filename);
  135.     Bitmap.Width:= Image.Width;
  136.     Bitmap.Height:= Image.Height;
  137.     Bitmap.Canvas.Draw(0,0,Image.Graphic);
  138.   finally
  139.     Image.Free;
  140.   end;
  141. end;
  142.  
  143. // Ajusta el bitmap a las mediddas correctas, recortandolo si es necesario
  144. procedure BitmapToFrame(Bitmap, Frame: TBitmap; Zoom: Real; Align: Integer);
  145. var
  146.   Ancho, Alto: integer;
  147.   i, j: integer;
  148. begin
  149.   Ancho:= FrameWidth;
  150.   Alto:= FrameHeight;
  151.   if  (Ancho/Bitmap.Width) > (Alto/Bitmap.Height) then
  152.     Alto:= Trunc((Ancho*Bitmap.Height)/Bitmap.Width)
  153.   else
  154.     Ancho:= Trunc((Bitmap.Width*Alto)/Bitmap.Height);
  155.   Ancho:= Trunc(Ancho * Zoom);
  156.   Alto:= Trunc(Alto * Zoom);
  157.   Frame.Width:= FrameWidth;
  158.   Frame.Height:= FrameHeight;
  159.   i:= ((Frame.Width - Ancho)) * Align div 128;
  160.   j:= ((Frame.Height - Alto)) * Align div 128;
  161.   Frame.Canvas.StretchDraw(Rect(i,j,Ancho + i,Alto + j),Bitmap);
  162. end;
  163.  
  164. // Repite el ultimo frame tantas veces como se le indique
  165. procedure Loop(Frames: Integer);
  166. begin
  167.   while Frames > 0 do
  168.   begin
  169.     WriteFrame(LastFrame);
  170.     dec(Frames);
  171.   end;
  172. end;
  173.  
  174. // Hace la transicion entre el ultimo frame y el bitmap que se le pasa como parametro
  175. procedure Transition(Bitmap: TBitmap);
  176. var
  177.   i: integer;
  178.   Frame: TBitmap;
  179. begin
  180.   Frame:= TBitmap.Create;
  181.   try
  182.     for i:= 1 to 64 do
  183.     begin
  184.       Frame.Assign(LastFrame);
  185.       Fade(Frame,Bitmap,i, FALSE);
  186.       WriteFrame(Frame);
  187.     end;
  188.     LastFrame.Assign(Bitmap);
  189.     WriteFrame(LastFrame);
  190.   finally
  191.     Frame.Free;
  192.   end;
  193. end;
  194.  
  195. // Muestra un texto que va apareciendo con una transicion
  196. procedure TextAnimation(Text: string; Color: TColor; Size: Integer);
  197. var
  198.   Bitmap: TBitmap;
  199. begin
  200.   Bitmap:= TBitmap.Create;
  201.   with Bitmap, Bitmap.Canvas do
  202.   try
  203.     Bitmap.Assign(LastFrame);
  204.     Font.Name:= &#39;Arial&#39;;
  205.     Font.Size:= Size;
  206.     Font.Color:= Color;
  207.     Font.Style:= [fsBold];
  208.     Brush.Style:= bsClear;
  209.     TextOut((Width - TextWidth(Text)) shr 1,
  210.       (Height - TextHeight(Text)) shr 1, Text);
  211.     Transition(Bitmap);
  212.   finally
  213.     Free;
  214.   end;
  215. end;
  216.  
  217. // Muestra un texto que va aparecido letra a letra
  218. procedure TypeWriter(Text: string; Color: TColor; Size: Integer);
  219. var
  220.   i: integer;
  221.   Bitmap: TBitmap;
  222. begin
  223.   Bitmap:= TBitmap.Create;
  224.   with Bitmap,Bitmap.Canvas do
  225.   try
  226.     Font.Name:= &#39;Arial&#39;;
  227.     Font.Size:= Size;
  228.     Font.Color:= Color;
  229.     Font.Style:= [fsBold];
  230.     Brush.Style:= bsClear;
  231.     i:= (LastFrame.Width - TextWidth(Text)) shr 1;
  232.     while Length(Text) > 0 do
  233.     begin
  234.       if Copy(Text,1,1) <> #32 then
  235.       begin
  236.         Bitmap.Assign(LastFrame);
  237.         TextOut(i,(Height - TextHeight(Copy(Text,1,1))) shr 1, Copy(Text,1,1));
  238.         Transition(Bitmap);
  239.       end;
  240.       inc(i,TextWidth(Copy(Text,1,1)));
  241.       Delete(Text,1,1);
  242.     end;
  243.   finally
  244.     Free;
  245.   end;
  246. end;
  247.  
  248.  
  249. // Muestraa un texto que va apareciendo letra a letra deslizandose
  250. procedure TextSlide(Text: string; Color: TColor; Size: Integer);
  251. var
  252.   i,j: integer;
  253.   Bitmap: TBitmap;
  254. begin
  255.   Bitmap:= TBitmap.Create;
  256.   with Bitmap,Bitmap.Canvas do
  257.   try
  258.     Font.Name:= &#39;Arial&#39;;
  259.     Font.Size:= Size;
  260.     Font.Color:= Color;
  261.     Font.Style:= [fsBold];
  262.     Brush.Style:= bsClear;
  263.     i:= (LastFrame.Width - TextWidth(Text)) shr 1;
  264.     while Length(Text) > 0 do
  265.     begin
  266.       if Copy(Text,1,1) <> #32 then
  267.       begin
  268.         for j:= 32 downto 0 do
  269.         begin
  270.           Bitmap.Assign(LastFrame);
  271.           TextOut(i + (((Width - i)*j) shr 5),
  272.             (Height - TextHeight(Copy(Text,1,1))) shr 1, Copy(Text,1,1));
  273.           WriteFrame(Bitmap);
  274.         end;
  275.         LastFrame.Assign(Bitmap);
  276.       end;
  277.       inc(i,TextWidth(Copy(Text,1,1)));
  278.       Delete(Text,1,1);
  279.     end;
  280.   finally
  281.     Free;
  282.   end;
  283. end;
  284.  
  285. // Acerca la imagen
  286. procedure Zoom(Bitmap: TBitmap; Steps: Integer);
  287. var
  288.   i: integer;
  289.   Frame: TBitmap;
  290. begin
  291.   Frame:= TBitmap.Create;
  292.   try
  293.     Frame.PixelFormat:= pf24bit;
  294.     for i:= 1 to Steps do
  295.     begin
  296.       BitmapToFrame(Bitmap,Frame,1 + ((0.5 * i) / Steps),64);
  297.       WriteFrame(Frame);
  298.     end;
  299.     LastFrame.Assign(Frame);
  300.   finally
  301.     Frame.Free
  302.   end;
  303. end;
  304.  
  305. // Mueve la "camara" por la imagen
  306. procedure Paneo(Bitmap: TBitmap; Steps: Integer);
  307. var
  308.   i: integer;
  309.   Frame: TBitmap;
  310. begin
  311.   Frame:= TBitmap.Create;
  312.   try
  313.     Frame.PixelFormat:= pf24bit;
  314.     for i:= 1 to Steps do
  315.     begin
  316.       BitmapToFrame(Bitmap,Frame,1 + ((0.5 * i) / Steps),i*128 div Steps);
  317.       WriteFrame(Frame);
  318.     end;
  319.     LastFrame.Assign(Frame);
  320.   finally
  321.     Frame.Free
  322.   end;
  323. end;
  324.  
  325. // Crea una secuencia a partir de las imagenes en la lista
  326. // Con el parametro coun le decimos cuantas imagenes debe usar
  327. procedure Sequence(Count: integer);
  328. var
  329.   Bitmap: TBitmap;
  330.   Frame: TBitmap;
  331. begin
  332.   Bitmap:= TBitmap.Create;
  333.   Frame:= TBitmap.Create;
  334.   try
  335.     Bitmap.PixelFormat:= pf24bit;
  336.     Frame.PixelFormat:= pf24bit;
  337.     while (ImgList.Count > 0) and (Count > 0) do
  338.     begin
  339.       FileToBitmap(Bitmap,ImgList[0]);
  340.       BitmapToFrame(Bitmap,Frame,1,64);
  341.       Transition(Frame);
  342.       Loop(64);
  343.       if Random(2)=0 then
  344.         Zoom(Bitmap,128)
  345.       else
  346.         Paneo(Bitmap,128);
  347.       ImgList.Delete(0);
  348.       Dec(Count);
  349.     end;
  350.   finally
  351.     Bitmap.Free;
  352.     Frame.Free;
  353.   end;
  354. end;
  355.  
  356. // Muestra una imagen estatica durante varios frames
  357. procedure InsertBanner(Banner: string; Frames: Integer);
  358. var
  359.   Bitmap: TBitmap;
  360.   Frame: TBitmap;
  361. begin
  362.   Bitmap:= TBitmap.Create;
  363.   Frame:= TBitmap.Create;
  364.   try
  365.     Bitmap.PixelFormat:= pf24bit;
  366.     Frame.PixelFormat:= pf24bit;
  367.     FileToBitmap(Bitmap,Banner);
  368.     BitmapToFrame(Bitmap,Frame,1,64);
  369.     Transition(Frame);
  370.     Loop(Frames);
  371.   finally
  372.     Bitmap.Free;
  373.     Frame.Free;
  374.   end;
  375. end;
  376.  
  377. procedure DeleteAll;
  378. var
  379.   SR: TSearchRec;
  380.   Count: Cardinal;
  381. begin
  382.   Count:= 0;
  383.   if FindFirst(AppPath + &#39;seq\*.*&#39;, faArchive, SR) = 0 then
  384.   repeat
  385.     DeleteFile(AppPath + &#39;seq\&#39; + SR.Name);
  386.     inc(Count);
  387.   until FindNext(SR) <> 0;
  388.   FindClose(SR);
  389.   Writeln(Format(&#39;%d Archivo(s) borrado(s)&#39;,[Count]));
  390. end;
  391.  
  392. // Carga la lista de imagenes a partir del directorio img
  393. procedure LoadList(Path: string);
  394. var
  395.   SR: TSearchRec;
  396. begin
  397.   if FindFirst(AppPath + Path + &#39;*.*&#39;, faArchive, SR) = 0 then
  398.   repeat
  399.     ImgList.Add(AppPath + Path + SR.Name);
  400.   until FindNext(SR) <> 0;
  401.   FindClose(SR);
  402. end;
  403.  
  404. // Aqui hacemos el "script" que se debe seguir
  405. procedure Script;
  406. begin
  407.   Index:= 0;
  408.   DeleteAll;
  409.   InitLastFrame(clBlack);
  410.   FrameSize:= GetFrameSize;
  411.   Writeln(Format(&#39;El tamaño de cada frame es: %d Kb&#39;,[FrameSize shr 10]));
  412.   Writeln;
  413.   Writeln(&#39;Progreso ...&#39;);
  414.   //FileToBitmap(FixedFrame,AppPath + &#39;\img\imagen_fija.bmp&#39;);
  415.   //FixedFrame.PixelFormat:= pf24bit;
  416.   LoadList(&#39;img\&#39;);
  417.   //ShowFixedFrame:= TRUE;
  418.   Sequence(ImgList.Count);  // Generamos una sola secuencia con todas las imagenes
  419.   {
  420.   O por ejemplo:
  421.   FadeLastFrame($C0C0C0,32);
  422.   TextSlide(&#39;Iberco&#39;, clBlack, 96);
  423.   Sequence(4);
  424.   FadeLastFrame($C0C0C0,32);
  425.   TextSlide(&#39;Iberco&#39;, clBlack, 96);
  426.   Sequence(4);
  427.   }
  428. end;
  429.  
  430. begin
  431.   Writeln;
  432.   Writeln(&#39;Creando secuencia de imagenes ...&#39;);
  433.   AppPath:= IncludeTrailingBackSlash(ExtractFilePath(ParamStr(0)));
  434.   Writeln(&#39;El directorio base es: &#39; + AppPath);
  435.   LastFrame:= TBitmap.Create;
  436.   FixedFrame:= TBitmap.Create;
  437.   ImgList:= TStringList.Create;
  438.   try
  439.     ShowFixedFrame:= FALSE;
  440.     Script;
  441.   finally
  442.     ImgList.Free;
  443.     LastFrame.Free;
  444.     FixedFrame.Free;
  445.   end;
  446.   Writeln;
  447.   Writeln;
  448.   Writeln(&#39;Pulsa "enter" para finalizar ...&#39;);
  449.   Writeln;
  450.   Readln;
  451.   // Aqui abrimos el virtualdub para crear el fichero de video
  452.   ShellExecute(0,nil,&#39;D:\VirtualDub-1.9.10\VirtualDub.exe&#39;,
  453.     &#39;"D:\make\seq\00000000.bmp"&#39;,nil, SW_SHOW);
  454. end.



Es una aplicación de consola. Las imágenes la toma de la carpeta "img" que tiene que estar en el mismo directorio que la aplicación y los frames generados los guarda en la carpeta "seq". En el procedure "script" es donde configuramos las diferentes secuencias y efectos.

Un consejo, hacer esto en un disco con abundante espacio libre. Unas pocas fotos, 20 o 30, pueden generar varios Gigabytes de frames así que tener esto en cuenta a la hora  de escoger la localización de las carpetas. Pero no os preocupéis, una vez cargado en el virtualdub podemos escoger un buen compresor (divx, xvid, etc ...) y el archivo avi resultante sera mucho mas pequeño.

Como ya he dicho, es reinventar la rueda, pero ... yo soy asi  :D



Archivos adjuntos


  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 10 octubre 2010 - 01:03

A ver si entendí amigo, creo una carpeta img para las imagenes, una carpeta seq para los frames creados y el programa VirtualDub dentro del directorio de esta aplicación ?

Salud OS
  • 0

#3 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 10 octubre 2010 - 01:24

Si descomprimes el zip ya tienes una carpeta img y otra seq dentro, no hace falta que las crees, solo tienes que meter fotos en la carpeta img.

El virtualdub puede estar en la carpeta que tu quieras, solo tienes que abrir el primer fichero bmp de la carpeta frames y listo. Si te fijas en el código yo lo llamo directamente, pero hay que cambiar la ruta dependiendo de donde tengas instalado el virtualdub
  • 0

#4 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 10 octubre 2010 - 01:46

Si, ya me di cuenta de eso :)

Pero si que consume buena cantidad de espacio, con solo 10 fotos ocupó la friolera de 3GB para crear los frames y el video (AVI) tambien  :(

Que lástima, quería subirles el slideshow, pero bueno les muestro de qué imágenes es :)

Salud OS

Archivos adjuntos


  • 0

#5 felipe

felipe

    Advanced Member

  • Administrador
  • 3.283 mensajes
  • LocationColombia

Escrito 10 octubre 2010 - 01:51

Cada día nos asombras más amigo (y)

Sería interesante aplicar el concepto que usas del fade en algo como un Panel o similar, de la misma forma en que funciona el AlphaBlend del formulario.


Saludos!
  • 0

#6 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 10 octubre 2010 - 02:21

Interesantes imágenes egostar :D

Lo del tamaño del avi puedes solucionarlo escogiendo un buen compresor en el virtualdub, en el menu "Video/Compresion" ahi puedes escoger, si lo tienes instalado, el divx o el xvid, o cualquiera similar. Por defecto no comprime nada así que el avi tienen el mismo tamaño que las imágenes originales.
  • 0

#7 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 10 octubre 2010 - 03:08

Interesantes imágenes egostar :D

Lo del tamaño del avi puedes solucionarlo escogiendo un buen compresor en el virtualdub, en el menu "Video/Compresion" ahi puedes escoger, si lo tienes instalado, el divx o el xvid, o cualquiera similar. Por defecto no comprime nada así que el avi tienen el mismo tamaño que las imágenes originales.


Ah, bueno vere que se puede hacer, no tengo instalados esos compresores, utilice uno de los que tiene y lo redujo a 1.5 MB, pero el video se ve al revés, que cosas  :D :D :D

Salud OS

Archivos adjuntos


  • 0

#8 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 11 octubre 2010 - 11:27

Buen ejemplo seoane

Sería interesante aplicar el concepto que usas del fade en algo como un Panel o similar, de la misma forma en que funciona el AlphaBlend del formulario.


Puedes revisar este tema para ver como realizar efectos de transparencias, en concreto usando la API AlphaBlend.

Saludos.
  • 0

#9 felipe

felipe

    Advanced Member

  • Administrador
  • 3.283 mensajes
  • LocationColombia

Escrito 11 octubre 2010 - 02:13

Buen ejemplo seoane


Sería interesante aplicar el concepto que usas del fade en algo como un Panel o similar, de la misma forma en que funciona el AlphaBlend del formulario.


Puedes revisar este tema para ver como realizar efectos de transparencias, en concreto usando la API AlphaBlend.

Saludos.


Gracias amigo por recordarmelo (y)

Sirve mucho para "jugar" con el diseño de interfaces.


Saludos!
  • 0

#10 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 11 octubre 2010 - 04:36

Puedes revisar este tema para ver como realizar efectos de transparencias, en concreto usando la API AlphaBlend.


Gracias, ya no me acordaba de ese tema. Y eso que en su momento te di las gracias :-D
  • 0

#11 felipe

felipe

    Advanced Member

  • Administrador
  • 3.283 mensajes
  • LocationColombia

Escrito 11 octubre 2010 - 04:55

egostar, aún esperamos el video :D


Saludos!
  • 0

#12 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 11 octubre 2010 - 05:08

egostar, aún esperamos el video :D


Saludos!


:D :D :D Pues parece que será mejor que te envíe un DVD por mensajería :p

Salud OS
  • 0

#13 felipe

felipe

    Advanced Member

  • Administrador
  • 3.283 mensajes
  • LocationColombia

Escrito 11 octubre 2010 - 06:01


egostar, aún esperamos el video :D


Saludos!


:D :D :D Pues parece que será mejor que te envíe un DVD por mensajería :p

Salud OS


Pues usa el Format Factory :p

:D

Saludos!
  • 0




IP.Board spam blocked by CleanTalk.