1

I'm trying to get x number of animated gifs to render on like a Panel or PictureBox and using transparency that is in each gif. I've tried a couple approaches but am not super famiular with ffmpeg and such. Below is some code that I use to get it to render inside a panel, but I can't figure out how to get like 5 gifs to stack/layer on one another and still render as you would expect.

I need/want this to render in the form and not outputted. I am a little confused to why the ffplay.exe doesn't use the -i command and that might be why i can't get it to render. any ideas?

Working example below.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Drawing.Text;
using System.Text.RegularExpressions;
using System.Configuration;
using Microsoft.Win32;
using System.Windows.Forms.VisualStyles;

//FOR THIS EXAMPLE CREATE FORM HAVE BUTTON ON IT AND PANEL.
//button: button's click is "button1_Click"
//panel: Needed to output the render on it.
//FILES:
//Test.Gif
//These ff files came from the ffmpeg offical site.
//ffplay.exe //currently using
//ffmpeg.exe //thinking i need to use to get it how I want.
//I most of the code below from https://stackoverflow.com/questions/31465630/ffplay-successfully-moved-inside-my-winform-how-to-set-it-borderless which was a good starting point.

namespace Test_Form
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

        [DllImport("user32.dll")]
        private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);


        //Process ffplay = null;

        public Form1()
        {
            InitializeComponent();
            Application.EnableVisualStyles();
            this.DoubleBuffered = true;
        }



        public Process ffplay = new Process();
        private void FFplay()
        {
            ffplay.StartInfo.FileName = "ffplay.exe";
            ffplay.StartInfo.Arguments = "-noborder Test.gif"; //THIS IS WHERE I INPUT THE GIF FILE
            ffplay.StartInfo.CreateNoWindow = true;
            ffplay.StartInfo.RedirectStandardOutput = true;
            ffplay.StartInfo.UseShellExecute = false;

            ffplay.EnableRaisingEvents = true;
            ffplay.OutputDataReceived += (o, e) => Debug.WriteLine(e.Data ?? "NULL", "ffplay");
            ffplay.ErrorDataReceived += (o, e) => Debug.WriteLine(e.Data ?? "NULL", "ffplay");
            ffplay.Exited += (o, e) => Debug.WriteLine("Exited", "ffplay");
            ffplay.Start();

            Thread.Sleep(1000); // you need to wait/check the process started, then...

            // child, new parent
            // make 'this' the parent of ffmpeg (presuming you are in scope of a Form or Control)
            SetParent(ffplay.MainWindowHandle, this.Handle);

            // window, x, y, width, height, repaint
            // move the ffplayer window to the top-left corner and set the size to 320x280
            MoveWindow(ffplay.MainWindowHandle, 800, 600, 320, 280, true);

            SetParent(ffplay.MainWindowHandle, this.panel1.Handle);
            MoveWindow(ffplay.MainWindowHandle, -5, -30, 320, 280, true);
        }

//runs the FFplay Command
private void button1_Click(object sender, EventArgs e)
        {
            FFplay();

        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            try { ffplay.Kill(); }
            catch { }
        }
    }

I would like the button to allow me to add any number of gifs (like 5 or 10) all to the same area and have them being animated with their transparent showing what is under that gif.

So for example I could have a circle image, then a spinning/loading transparent gif on top, and then a gif that counts up/down on top of that one to give me the effect of a count-down.

Thanks for all the help!

Purqs
  • 11
  • 1
  • You don't need ffplay : Picture Boxes can play animated GIF and you can make them transparent. A test with **SetLayeredWindowAttributes** to make 2 Picture Boxes transparent with animated GIF : [Transparent animated Picture Boxes](https://i.ibb.co/Tr6PpwY/transparent-picture.gif) – Castorix Jun 17 '19 at 20:07
  • You can just assign the Image to the PictureBox, setting its BackColor to `Color.Transparent`. Don't expect outstanding results. – Jimi Jun 17 '19 at 20:30
  • Thanks for your input. I did attempt this with picture boxes, but alas it doesn't have outstanding results as Jim said, plus it won't render past a certain number of layers making it far more limited on what can/can't be done. The gifs under 2 or 3 picture boxes sometimes don't render at all or very choppy/slow. I was thinking I could use ffmpeg for rendering these out but need it to work with small scale samples of just getting like 5 gifs over-lapping and rendering all at once at 30fps minimum. I've been looking into other methods of doing this and there are not many options. – Purqs Jun 18 '19 at 15:18
  • Try the [ImageAnimator](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.imageanimator) class (it's the class that the PictureBox control uses to animate the frames of a Bitmap). It works somewhat better *outside* the PictureBox. Don't even think about more that 30 fps in WinForms, it's simply not possible. – Jimi Jun 19 '19 at 07:39

0 Answers0