Welcome to mirror list, hosted at ThFree Co, Russian Federation.

LayerCache.cs « UVtools.WPF - github.com/sn4k3/UVtools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: dc5ae589f71e2247386c00ef33c296c99f79c205 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 *                     GNU AFFERO GENERAL PUBLIC LICENSE
 *                       Version 3, 19 November 2007
 *  Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 *  Everyone is permitted to copy and distribute verbatim copies
 *  of this license document, but changing it is not allowed.
 */

using System;
using Avalonia.Media.Imaging;
using Avalonia.Skia;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Util;
using SkiaSharp;
using UVtools.Core;
using UVtools.Core.Extensions;

namespace UVtools.WPF
{
    public sealed class LayerCache
    {
        private Layer _layer;
        private Array _layerHierarchyJagged;
        private VectorOfVectorOfPoint _layerContours;
        private Mat _layerHierarchy;
        //private SKCanvas _canvas;
        private WriteableBitmap _bitmap;

        public bool IsCached => _layer is not null;

        public unsafe Layer Layer
        {
            get => _layer;
            set
            {
                //if (ReferenceEquals(_layer, value)) return;
                Clear();
                _layer = value;
                Image = _layer.LayerMat;
                ImageBgr = new Mat();
                CvInvoke.CvtColor(Image, ImageBgr, ColorConversion.Gray2Bgr);

                ImageSpan = Image.GetBytePointer();
                ImageBgrSpan = ImageBgr.GetBytePointer();
            }
        }

        public Mat Image { get; private set; }

        public Mat ImageBgr { get; private set; }

        public unsafe byte *ImageSpan { get; private set; }
        public unsafe byte *ImageBgrSpan { get; private set; }

        public WriteableBitmap Bitmap
        {
            get => _bitmap;
            set
            {
                _bitmap = value;
                //_canvas?.Dispose();
                //_canvas = null;
            }
        }

        public SKCanvas Canvas
        {
            get
            {
                using var framebuffer = Bitmap.Lock();
                var info = new SKImageInfo(framebuffer.Size.Width, framebuffer.Size.Height,
                    framebuffer.Format.ToSkColorType(), SKAlphaType.Premul);
                return SKSurface.Create(info, framebuffer.Address, framebuffer.RowBytes).Canvas;
            }
        }

        public VectorOfVectorOfPoint LayerContours
        {
            get
            {
                if (_layerContours is null) CacheContours();
                return _layerContours;
            }
            private set => _layerContours = value;
        }

        public Mat LayerHierarchy
        {
            get
            {
                if (_layerHierarchy is null) CacheContours();
                return _layerHierarchy;
            }
            private set => _layerHierarchy = value;
        }

        public Array LayerHierarchyJagged
        {
            get
            {
                if(_layerHierarchyJagged is null) CacheContours();
                return _layerHierarchyJagged;
            }
            private set => _layerHierarchyJagged = value;
        }

        public void CacheContours(bool refresh = false)
        {
            if(refresh) Clear();
            if (_layerContours is not null) return;
            _layerContours = new VectorOfVectorOfPoint();
            _layerHierarchy = new Mat();
            CvInvoke.FindContours(Image, _layerContours, _layerHierarchy, RetrType.Ccomp,
                ChainApproxMethod.ChainApproxSimple);
            _layerHierarchyJagged = _layerHierarchy.GetData();
        }
        

        /// <summary>
        /// Clears the cache
        /// </summary>
        public void Clear()
        {
            _layer = null;
            Image?.Dispose();
            ImageBgr?.Dispose();
            _layerContours?.Dispose();
            _layerContours = null;
            _layerHierarchy?.Dispose();
            _layerHierarchy = null;
            _layerHierarchyJagged = null;
        }
    }
}