SuRGeoNix / Flyleaf

Media Player .NET Library for WinUI 3/ WPF/WinForms (based on FFmpeg/DirectX)
GNU Lesser General Public License v3.0
715 stars 101 forks source link

Draw a rectangle on video #153

Closed pubpy2015 closed 2 years ago

pubpy2015 commented 2 years ago

Hi,

Can i using Renderer.cs to draw a rectangle on video ? Purpose: draw rectangle on video, camerra will zoom to it (drag to zoom or 3d ptz function) ảnh https://www.youtube.com/watch?v=r9dRv7ls_5c

SuRGeoNix commented 2 years ago

HI @pubpy2015,

I think you could handle the rectangle drawing on your application. No need to included in the renderer. (I'm not sure for WinForms if you don't use WPF yet). What I could support in the library would be to cut a specific area of a video and fit it to the whole screen (which is actually zooming on specific rectangle).

pubpy2015 commented 2 years ago

Thank for your support,

I am using WinForm. I remember that, in previous version (may be 1xx or 2xx) you have a PresentOSD method, it can be draw subtitle string (may be can draw rectangle) on video,. How can i do that with this version ?

SuRGeoNix commented 2 years ago

Well, this is gonna be tricky... I did a quick test with the following code in the renderer (see attached)

Make sure you set the video processor to flyleaf at your application with

Player.Config.Video.VideoProcessor = VideoProcessors.Flyleaf;

1) Include Vortice.Direct2D1 nuget package (make sure same version with the already installed)

using Vortice.Direct2D1;
using Filter = Vortice.Direct3D11.Filter;
using FeatureLevel = Vortice.Direct3D.FeatureLevel;

2) Variables

ID2D1RenderTarget       rt2d;
ID2D1Brush              brush2d;

3) Initialize()

ID2D1Factory2 factory2 = D2D1.D2D1CreateFactory<ID2D1Factory2>(FactoryType.MultiThreaded);
RenderTargetProperties rtp = new RenderTargetProperties();

rtp.PixelFormat.Format = Format.Unknown;
rtp.PixelFormat.AlphaMode = Vortice.DCommon.AlphaMode.Ignore;

rt2d = factory2.CreateDxgiSurfaceRenderTarget(backBuffer.QueryInterface<IDXGISurface>(), rtp);
brush2d = rt2d.CreateSolidColorBrush(new Color4(Colors.Red));

4) PresentInternal()

Add Draw2D() after context.Draw(6, 0); and before swapChain.Present(...)

Draw2D();

5) Draw2D() new method

public void Draw2D()
{
    rt2d.BeginDraw();
    rt2d.DrawRectangle(new RawRectF(0, 0, 100, 100), brush2d);
    rt2d.EndDraw();
}

6) Disposal should be take care as well

It creates issues with WPF and D3D11 Video processor that's why I said it could be tricky to make sure everything works ok.

Renderer.cs.txt

pubpy2015 commented 2 years ago

Thanks,

It's work fine! ảnh

SuRGeoNix commented 2 years ago

I saw some strange behavior when you go on full screen. Changes the video position. You will still need the cut video method, or you ok?

pubpy2015 commented 2 years ago

I am ok. I will write my own video player base on your FlyLeaf, work like video bellow:

https://user-images.githubusercontent.com/59004953/166879954-3a382ea6-747a-425e-ae4d-d6ae98a582ca.mp4

pubpy2015 commented 2 years ago

Looks like this modification can't work with your latest code.

SuRGeoNix commented 2 years ago

I see the same results as the last time, works fine but not in full screen which does a strange zoom. Did you update Direct2D1 package to the same version with other libs?

SuRGeoNix commented 2 years ago

OK I did some corrections and fixed also the issue with full screen and added proper disposal but keep in mind I will not be able to keep track of that as I'm currently not including this.

Renderer.cs.txt

pubpy2015 commented 2 years ago

Thank you very much. Now it works fine.

pubpy2015 commented 2 years ago

Hi,

Please help me draw a polygon. I dont see DrawPolygon method of rtv2d.

SuRGeoNix commented 2 years ago

I will have to see how as well so I'm afraid can't help you now with that.

pubpy2015 commented 2 years ago

I am using this code: `using (ID2D1PathGeometry1 geometry = factory2.CreatePathGeometry()) { using (ID2D1GeometrySink geometrySink = geometry.Open()) { rtv2d.BeginDraw(); //rtv2d.DrawRectangle(new RawRectF(0, 0, 100, 100), brush2d);

                geometrySink.BeginFigure(new System.Numerics.Vector2(
                    points[0].X,
                    points[0].Y),
                    FigureBegin.Filled);
                for (int i = 1; i < points.Count; i++)
                {
                    geometrySink.AddLine(new System.Numerics.Vector2(
                        points[i].X,
                        points[i].Y));
                }

                geometrySink.EndFigure(FigureEnd.Closed);
                geometrySink.Close();

                rtv2d.DrawGeometry(geometry, brush2d, 2f);
                rtv2d.EndDraw();
            }
        }`