C# 为什么pictureBox中的图像显示为镜像?而且也不';不合适吗?

C# 为什么pictureBox中的图像显示为镜像?而且也不';不合适吗?,c#,C#,这是我将帧/图像保存到硬盘的代码 我将图像旋转两次,每次180度,然后再次旋转90度 但视频显示,这名女子从左向右行走,但在旋转后,我在图片框中看到她使用轨迹条滚动从右向左移动,就像一面镜子一样 这是旋转后的样子: public static Image RotateImage(Image img, float rotationAngle) { //create an empty Bitmap image Bitmap bmp =

这是我将帧/图像保存到硬盘的代码

我将图像旋转两次,每次180度,然后再次旋转90度

但视频显示,这名女子从左向右行走,但在旋转后,我在图片框中看到她使用轨迹条滚动从右向左移动,就像一面镜子一样

这是旋转后的样子:

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;
        }

她开始从右向左走,她的脸在向左看的时候,原来应该是从左向右的

这是我将其旋转180度时的外观,这也是原始视频文件中的外观:

我想看到的是她在第一张图片中的样子,但是像应该的那样从左向右走。就像在第二张图片中,她的脸指向右边

这是我正在使用的代码:

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;
        }
但它没有做到

我怎么做

我正在尝试使用此函数进行旋转:

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;
        }
然后我就这样使用它:

Bitmap t = new Bitmap(RotateImage(bitmap, 180));
t.Save(Path.Combine(_outFolder, _frameId.ToString("D6") + ".bmp"));
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;
            }
        }
但它不会向右旋转180或90度!它使它成为一面镜子。 如果她的脸指向右边的第二张图片,我想把图片向右转90度,这样她会站在那里,脸朝右边!!! 但是我却发现她总是脸朝左,像一面镜子

为什么?

这是从视频文件中提取帧并将其保存到硬盘的类:

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;
        }*/
    }
}
我试过了

bitmap1.RotateFlip(RotateFlipType.RotateNoneFlipX);
而且似乎能按要求工作

实际上,
RotateFlipType.Rotate180FlipX
将图像旋转180度,然后在X轴上翻转,将所有内容返回初始位置


如果我错了,请纠正我,我不是一个图形专家。

你为什么要使用
RotateFlip
呢?Oded,我不是随课提供的。我以前从未在图像上使用过旋转。但是你建议以后用什么来代替RotateFlip呢?你真的不需要每次都在标题后面加上“EDITED**”。没有必要,更不用说讨厌了。我发现从视频文件中提取图像/帧时,硬盘上的帧已经被镜像了。这是一个视频文件的链接:我将更新我的问题,并将我用于提取的类以及我如何使用它,也许有人能找到它镜像帧的原因?使用位图.RotateFlip(RotateFlipType.Rotate270FlipY);现在它开始工作了。