Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Gtk3中使用Skia在Cairo上下文中绘图_C#_Cairo_Gtk#_Skia - Fatal编程技术网

C# 如何在Gtk3中使用Skia在Cairo上下文中绘图

C# 如何在Gtk3中使用Skia在Cairo上下文中绘图,c#,cairo,gtk#,skia,C#,Cairo,Gtk#,Skia,我希望得到彩色矩形,但得到垃圾矩形。到目前为止,我有以下代码: using System; using GLib; using SkiaSharp; using Gtk; namespace SkiaSharpExample { class CCDrawingArea : DrawingArea { protected override bool OnDrawn (Cairo.Context cr) { using (var skSurface

我希望得到彩色矩形,但得到垃圾矩形。到目前为止,我有以下代码:

using System;
using GLib;
using SkiaSharp;
using Gtk;

namespace SkiaSharpExample {
    class CCDrawingArea : DrawingArea {
        protected override bool OnDrawn (Cairo.Context cr) {
            using (var skSurface = SKSurface.Create (100, 100, SKColorType.N_32, SKAlphaType.Premul)) {
                var canvas = skSurface.Canvas;
                var paint = new SKPaint {
                    StrokeWidth = 4, 
                    Color = new SKColor (255, 255, 255, 255)
                };

                var rect = new SKRect (10, 10, 50, 50);
                canvas.DrawRect (rect, paint);

                var image = skSurface.Snapshot ();

                Cairo.Surface surface = new Cairo.ImageSurface (
                    image.Encode ().Data,
                    Cairo.Format.Argb32,
                    image.Width, image.Height,
                    4 * image.Width * image.Height);

                surface.MarkDirty ();
                cr.SetSourceSurface (surface, 0, 0);
                cr.Paint ();
            }
            return true;
        }
    }

    class MainClass {
        public static void Main (string[] args){
            ExceptionManager.UnhandledException += delegate(UnhandledExceptionArgs expArgs) {
                Console.WriteLine (expArgs.ExceptionObject.ToString ());
                expArgs.ExitApplication = true;
            };

            Gtk.Application.Init ();

            var window = new Window ("Hello World");
            window.SetDefaultSize (1024, 800);
            window.SetPosition (WindowPosition.Center);
            window.DeleteEvent += delegate { 
                Gtk.Application.Quit (); 
            };

            var darea = new CCDrawingArea ();
            window.Add (darea);

            window.ShowAll ();

            Gtk.Application.Run ();
        }
    }
}

我对Skia没有任何线索,也找不到任何关于其图像格式的文档,但这里的最后一个参数应该是stride。自然步幅为
4*image.Width
。斯基亚也是这么用的吗?(步幅是像素开头和该像素下面的像素之间的字节数)


我找到了在创建SKSurface和SKCanvas之前应该使用SKBitmap的解决方案。要获取像素数据,我应该使用SKBitmap.GetPixels方法。下面是工作示例的源代码:

    using System;
    using GLib;
    using SkiaSharp;
    using Gtk;

    namespace SkiaSharpExample
    {
        class CCDrawingArea : DrawingArea
        {
            protected override bool OnDrawn(Cairo.Context cr)
            {
                const int width = 100;
                const int height = 100;

                using (var bitmap = new SKBitmap(width, height, SKColorType.N_32, SKAlphaType.Premul))
                {
                    IntPtr len;
                    using (var skSurface = SKSurface.Create(bitmap.Info.Width, bitmap.Info.Height, SKColorType.N_32, SKAlphaType.Premul, bitmap.GetPixels(out len), bitmap.Info.RowBytes))
                    {
                        var canvas = skSurface.Canvas;
                        canvas.Clear(SKColors.White);

                        using (var paint = new SKPaint())
                        {
                            paint.StrokeWidth = 4;
                            paint.Color = new SKColor(0x2c, 0x3e, 0x50);

                            var rect = new SKRect(10, 10, 50, 50);
                            canvas.DrawRect(rect, paint);
                        }

                        Cairo.Surface surface = new Cairo.ImageSurface(
                            bitmap.GetPixels(out len),
                            Cairo.Format.Argb32,
                            bitmap.Width, bitmap.Height,
                            bitmap.Width * 4);


                        surface.MarkDirty();
                        cr.SetSourceSurface(surface, 0, 0);
                        cr.Paint();
                    }
                }

                return true;
            }
        }

        class MainClass
        {
            public static void Main(string[] args)
            {
                ExceptionManager.UnhandledException += delegate(UnhandledExceptionArgs expArgs)
                {
                    Console.WriteLine(expArgs.ExceptionObject.ToString());
                    expArgs.ExitApplication = true;
                };

                Gtk.Application.Init();

                var window = new Window("Hello Skia World");
                window.SetDefaultSize(1024, 800);
                window.SetPosition(WindowPosition.Center);
                window.DeleteEvent += delegate
                {
                    Gtk.Application.Quit();
                };

                var darea = new CCDrawingArea();
                window.Add(darea);

                window.ShowAll();

                Gtk.Application.Run();
            }

            void OnException(object o, UnhandledExceptionArgs args)
            {

            }
        }
    }

是的,这是问题的一部分,我应该使用4*image.width此代码仅适用于
Cairo.Format.Argb32
SKColorType.N_32
定义相同A-R-G-B顺序的窗口。在Linux和Mac上
SKColorType.N_32
A-B-G-R
    using System;
    using GLib;
    using SkiaSharp;
    using Gtk;

    namespace SkiaSharpExample
    {
        class CCDrawingArea : DrawingArea
        {
            protected override bool OnDrawn(Cairo.Context cr)
            {
                const int width = 100;
                const int height = 100;

                using (var bitmap = new SKBitmap(width, height, SKColorType.N_32, SKAlphaType.Premul))
                {
                    IntPtr len;
                    using (var skSurface = SKSurface.Create(bitmap.Info.Width, bitmap.Info.Height, SKColorType.N_32, SKAlphaType.Premul, bitmap.GetPixels(out len), bitmap.Info.RowBytes))
                    {
                        var canvas = skSurface.Canvas;
                        canvas.Clear(SKColors.White);

                        using (var paint = new SKPaint())
                        {
                            paint.StrokeWidth = 4;
                            paint.Color = new SKColor(0x2c, 0x3e, 0x50);

                            var rect = new SKRect(10, 10, 50, 50);
                            canvas.DrawRect(rect, paint);
                        }

                        Cairo.Surface surface = new Cairo.ImageSurface(
                            bitmap.GetPixels(out len),
                            Cairo.Format.Argb32,
                            bitmap.Width, bitmap.Height,
                            bitmap.Width * 4);


                        surface.MarkDirty();
                        cr.SetSourceSurface(surface, 0, 0);
                        cr.Paint();
                    }
                }

                return true;
            }
        }

        class MainClass
        {
            public static void Main(string[] args)
            {
                ExceptionManager.UnhandledException += delegate(UnhandledExceptionArgs expArgs)
                {
                    Console.WriteLine(expArgs.ExceptionObject.ToString());
                    expArgs.ExitApplication = true;
                };

                Gtk.Application.Init();

                var window = new Window("Hello Skia World");
                window.SetDefaultSize(1024, 800);
                window.SetPosition(WindowPosition.Center);
                window.DeleteEvent += delegate
                {
                    Gtk.Application.Quit();
                };

                var darea = new CCDrawingArea();
                window.Add(darea);

                window.ShowAll();

                Gtk.Application.Run();
            }

            void OnException(object o, UnhandledExceptionArgs args)
            {

            }
        }
    }