Why the image in the pictureBox is show as mirror ? And also doesn't fit right?

0

This is the code where I save the frames/images to the hard disk.

I rotate the images twice once in 180 degrees then once again in 90 degrees.

But the video show the woman walking from left to right but after the rotation I see it in the pictureBox using the trackBar scroll moving from right to left like a mirror.

This is how it looks like after the rotation:

enter image description here

She start to walk from right to left her face are looking to the left when in the original it should be from left to right.

This is how it looks when I rotate it to 180 degrees once that's how it looks also in the original video file:

enter image description here

What I want is to see her like in the first image but walking from left to right like it should be. Like in the second image her face point right !

This is the code I'm using:

int ISampleGrabberCB.BufferCB(double sampleTime, IntPtr pBuffer, int bufferLen)
        {
            using (var bitmap = new Bitmap(_width, _height, _width * 3, PixelFormat.Format24bppRgb, pBuffer))
            {
                bitmap.RotateFlip(RotateFlipType.Rotate180FlipX);
               // bitmap.RotateFlip(RotateFlipType.Rotate90FlipX);
                if (SaveToDisc)
                {
                    String tempFile = _outFolder+ _frameId.ToString("D6") + ".bmp";
                    if (File.Exists(tempFile))
                    {
                        if (lbl1.InvokeRequired)
                        {
                            lbl1.Invoke(new MethodInvoker(delegate { lbl1.Text = _frameId.ToString(); }));
                        }
                    }
                    else
                    {
                        bitmap.Save(Path.Combine(_outFolder, _frameId.ToString("D6") + ".bmp"));
                        if (lbl1.InvokeRequired)
                        {
                            lbl1.Invoke(new MethodInvoker(delegate { lbl1.Text = _frameId.ToString(); }));
                        }
                    }
                    _frameId++;
                }
                else
                {
                    if (Images == null)
                        Images = new List<Bitmap>();
                    Images.Add((Bitmap)bitmap.Clone());
                }
            }
            return 0;
        }

Now I rotate it once 180 degrees I tried to rotate it with another 90 degrees and then another 180 degrees but it didn't work.

I want to rotate the second image to the right in 90 degrees so I tried just:

bitmap.RotateFlip(RotateFlipType.Rotate90FlipX); 

but it didn't do it.

How can I do it ?

Im trying now to use this function for the rotation:

public static Image RotateImage(Image img, float rotationAngle)
        {
            //create an empty Bitmap image
            Bitmap bmp = new Bitmap(img.Width, img.Height);

            //turn the Bitmap into a Graphics object
            Graphics gfx = Graphics.FromImage(bmp);

            //now we set the rotation point to the center of our image
            gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);

            //now rotate the image
            gfx.RotateTransform(rotationAngle);

            gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);

            //set the InterpolationMode to HighQualityBicubic so to ensure a high
            //quality image once it is transformed to the specified size
            gfx.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            //now draw our new image onto the graphics object
            gfx.DrawImage(img, new Point(0, 0));

            //dispose of our Graphics object
            gfx.Dispose();

            //return the image
            return bmp;
        }

Then im using it like this:

Bitmap t = new Bitmap(RotateImage(bitmap, 180));
t.Save(Path.Combine(_outFolder, _frameId.ToString("D6") + ".bmp"));

But it dosent rotate it by 180 or 90 to the right ! Its making it mirror. If her face are pointing in the second image to the right i want to turn the image 90 degrees up to the right so she will stand with her face to the right !!! But instead im getting all the time that she is with the face to the left like a mirror.

Why ?

This is the class that extract the frames from the video file and save it to the hard disk:

using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using DirectShowLib;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Drawing;


namespace Polkan.DataSource
{
    internal class WmvAdapter : ISampleGrabberCB, IDisposable
    {
        #region Fields
        //public Image img;
        private IFilterGraph2 _filterGraph;
        private IMediaControl _mediaCtrl;
        private IMediaEvent _mediaEvent;
        private int _width;
        private int _height;
        private readonly string _outFolder;
        private int _frameId;
        private Label lbl1;
        public bool done;

        #endregion

        #region Constructors and Destructors

        public WmvAdapter(string file, string outFolder , Label lbl)
        {
            _outFolder = outFolder;
            lbl1 = lbl;
            try
            {
                SetupGraph(file);
            }
            catch
            {
                Dispose();
                MessageBox.Show("A codec is required to load this video file. Please use http://www.headbands.com/gspot/ or search the web for the correct codec");
                throw;
            }
        }

        ~WmvAdapter()
        {
            CloseInterfaces();
        }

        #endregion

        public void Dispose()
        {
            CloseInterfaces();
        }

        public void Start()
        {
            int hr = _mediaCtrl.Run();
            WaitUntilDone();
            DsError.ThrowExceptionForHR(hr);
        }

        public void WaitUntilDone()
        {
            int hr;
            const int eAbort = unchecked((int)0x80004004);

            do
            {

                System.Windows.Forms.Application.DoEvents();
                EventCode evCode;
                hr = _mediaEvent.WaitForCompletion(100, out evCode);
            } while 
                (hr == eAbort);

            DsError.ThrowExceptionForHR(hr);

                lbl1.ForeColor = Color.Red;
                lbl1.Invoke(new MethodInvoker(delegate { lbl1.Text = _frameId.ToString(); }));
                done = true;
        }

        /// <summary> build the capture graph for grabber. </summary>
        private void SetupGraph(string file)
        {
            ISampleGrabber sampGrabber = null;
            IBaseFilter capFilter = null;
            IBaseFilter nullrenderer = null;

            _filterGraph = (IFilterGraph2)new FilterGraph();
            _mediaCtrl = (IMediaControl)_filterGraph;
            _mediaEvent = (IMediaEvent)_filterGraph;

            var mediaFilt = (IMediaFilter)_filterGraph;

            try
            {
                // Add the video source
                int hr = _filterGraph.AddSourceFilter(file, "Ds.NET FileFilter", out capFilter);
                DsError.ThrowExceptionForHR(hr);

                // Get the SampleGrabber interface
                sampGrabber = new SampleGrabber() as ISampleGrabber;
                var baseGrabFlt = sampGrabber as IBaseFilter;

                ConfigureSampleGrabber(sampGrabber);

                // Add the frame grabber to the graph
                hr = _filterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber");
                DsError.ThrowExceptionForHR(hr);

                // ---------------------------------
                // Connect the file filter to the sample grabber

                // Hopefully this will be the video pin, we could check by reading it's mediatype
                IPin iPinOut = DsFindPin.ByDirection(capFilter, PinDirection.Output, 0);

                // Get the input pin from the sample grabber
                IPin iPinIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0);

                hr = _filterGraph.Connect(iPinOut, iPinIn);
                DsError.ThrowExceptionForHR(hr);

                // Add the null renderer to the graph
                nullrenderer = new NullRenderer() as IBaseFilter;
                hr = _filterGraph.AddFilter(nullrenderer, "Null renderer");
                DsError.ThrowExceptionForHR(hr);

                // ---------------------------------
                // Connect the sample grabber to the null renderer

                iPinOut = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Output, 0);
                iPinIn = DsFindPin.ByDirection(nullrenderer, PinDirection.Input, 0);

                hr = _filterGraph.Connect(iPinOut, iPinIn);
                DsError.ThrowExceptionForHR(hr);

                // Turn off the clock. This causes the frames to be sent
                // thru the graph as fast as possible
                hr = mediaFilt.SetSyncSource(null);
                DsError.ThrowExceptionForHR(hr);

                // Read and cache the image sizes
                SaveSizeInfo(sampGrabber);
            }
            finally
            {
                if (capFilter != null)
                {
                    Marshal.ReleaseComObject(capFilter);
                }
                if (sampGrabber != null)
                {
                    Marshal.ReleaseComObject(sampGrabber);
                }
                if (nullrenderer != null)
                {
                    Marshal.ReleaseComObject(nullrenderer);
                }
                GC.Collect();
            }
        }

        private void SaveSizeInfo(ISampleGrabber sampGrabber)
        {
            // Get the media type from the SampleGrabber
            var media = new AMMediaType();
            int hr = sampGrabber.GetConnectedMediaType(media);
            DsError.ThrowExceptionForHR(hr);

            if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
            {
                throw new NotSupportedException("Unknown Grabber Media Format");
            }

            // Grab the size info
            var videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader));
            _width = videoInfoHeader.BmiHeader.Width;
            _height = videoInfoHeader.BmiHeader.Height;

            DsUtils.FreeAMMediaType(media);
            GC.Collect();
        }

        private void ConfigureSampleGrabber(ISampleGrabber sampGrabber)
        {
            var media = new AMMediaType
            {
                majorType = MediaType.Video,
                subType = MediaSubType.RGB24,
                formatType = FormatType.VideoInfo
            };
            int hr = sampGrabber.SetMediaType(media);
            DsError.ThrowExceptionForHR(hr);

            DsUtils.FreeAMMediaType(media);
            GC.Collect();
            hr = sampGrabber.SetCallback(this, 1);
            DsError.ThrowExceptionForHR(hr);
        }

        private void CloseInterfaces()
        {
            try
            {
                if (_mediaCtrl != null)
                {
                    _mediaCtrl.Stop();
                    _mediaCtrl = null;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }

            if (_filterGraph != null)
            {
                Marshal.ReleaseComObject(_filterGraph);
                _filterGraph = null;
            }
            GC.Collect();
        }

        int ISampleGrabberCB.SampleCB(double sampleTime, IMediaSample pSample)
        {
            Marshal.ReleaseComObject(pSample);
            return 0;
        }

        //add a boolean property to indicate the save-mode
        public bool SaveToDisc { get; set; }
        //the list for the bitmaps
        public List<Bitmap> Images { get; set; }

        int ISampleGrabberCB.BufferCB(double sampleTime, IntPtr pBuffer, int bufferLen)
        {
            using (var bitmap = new Bitmap(_width, _height, _width * 3, PixelFormat.Format24bppRgb, pBuffer))
            {
                //bitmap.RotateFlip(RotateFlipType.RotateNoneFlipXY);
               // bitmap.RotateFlip(RotateFlipType.Rotate90FlipX);
               // Bitmap t = new Bitmap(RotateImage(bitmap, 180));
                if (SaveToDisc)
                {
                    String tempFile = _outFolder+ _frameId.ToString("D6") + ".bmp";
                    if (File.Exists(tempFile))
                    {
                        if (lbl1.InvokeRequired)
                        {
                            lbl1.Invoke(new MethodInvoker(delegate { lbl1.Text = _frameId.ToString(); }));
                        }

                    }
                    else
                    {
                        bitmap.Save(Path.Combine(_outFolder, _frameId.ToString("D6") + ".bmp"));
                        if (lbl1.InvokeRequired)
                        {
                            lbl1.Invoke(new MethodInvoker(delegate { lbl1.Text = _frameId.ToString(); }));
                        }
                    }
                    _frameId++;
                }
                else
                {
                    if (Images == null)
                        Images = new List<Bitmap>();
                    Images.Add((Bitmap)bitmap.Clone());
                }
            }
            return 0;
        }

        public static Image RotateImage(Image img, float rotationAngle)
        {
            //create an empty Bitmap image
            Bitmap bmp = new Bitmap(img.Width, img.Height);

            //turn the Bitmap into a Graphics object
            Graphics gfx = Graphics.FromImage(bmp);

            //now we set the rotation point to the center of our image
            gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);

            //now rotate the image
            gfx.RotateTransform(rotationAngle);

            gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);

            //set the InterpolationMode to HighQualityBicubic so to ensure a high
            //quality image once it is transformed to the specified size
            gfx.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            //now draw our new image onto the graphics object
            gfx.DrawImage(img, new Point(0, 0));

            //dispose of our Graphics object
            gfx.Dispose();

            //return the image
            return bmp;
        }



        /*int ISampleGrabberCB.BufferCB(double sampleTime, IntPtr pBuffer, int bufferLen)
        {
            using (var bitmap = new Bitmap(_width, _height, _width * 3, PixelFormat.Format24bppRgb, pBuffer))
            {
                bitmap.RotateFlip(RotateFlipType.Rotate180FlipX);
                MemoryStream myStream = new MemoryStream(1000000);
                bitmap.Save(myStream, ImageFormat.Bmp);
                //bitmap.Save(Path.Combine(_outFolder, _frameId + ".bmp")); 
                img = new Bitmap(myStream);

            }
            return 0;
        }*/
    }
}

And in Form1 im using the class like this:

private void button5_Click(object sender, EventArgs e)
        {
            button5.Enabled = false;
            button1.Enabled = false;
            wmv = new Polkan.DataSource.WmvAdapter(@"d:\VIDEO0040.3gp", sf,label2);
            wmv.SaveToDisc = true;
            wmv.Start();
            if (wmv.done == true)
            {
                button1.Enabled = true;
            }
        }
c#
asked on Stack Overflow Jul 1, 2012 by user1477444 • edited Jul 1, 2012 by user1477444

1 Answer

0

I have tried with

bitmap1.RotateFlip(RotateFlipType.RotateNoneFlipX);

and seems to work as requested.

Actually, RotateFlipType.Rotate180FlipX rotate the image of 180 degree, then flip on the X axis returning everything at the initial position.

Correct me if I'm wrong, I am not a graphic expert.

answered on Stack Overflow Jul 1, 2012 by Steve

User contributions licensed under CC BY-SA 3.0