示例#1
0
        public static void FlipImageUpDown(Array2DBase inputImage, Array2DBase outputImage)
        {
            if (inputImage == null)
            {
                throw new ArgumentNullException(nameof(inputImage));
            }
            if (outputImage == null)
            {
                throw new ArgumentNullException(nameof(outputImage));
            }
            if (inputImage == outputImage)
            {
                throw new ArgumentException();
            }

            inputImage.ThrowIfDisposed(nameof(inputImage));
            outputImage.ThrowIfDisposed(nameof(outputImage));

            var inType  = inputImage.ImageType.ToNativeArray2DType();
            var outType = outputImage.ImageType.ToNativeArray2DType();
            var ret     = NativeMethods.flip_image_up_down(inType, inputImage.NativePtr, outType, outputImage.NativePtr);

            switch (ret)
            {
            case NativeMethods.ErrorType.Array2DTypeTypeNotSupport:
                throw new ArgumentException("Output or input type is not supported.");
            }
        }
示例#2
0
        public static void ResizeImage(Array2DBase inputImage, Array2DBase outputImage, InterpolationTypes interpolationTypes = InterpolationTypes.Bilinear)
        {
            if (inputImage == null)
            {
                throw new ArgumentNullException(nameof(inputImage));
            }
            if (outputImage == null)
            {
                throw new ArgumentNullException(nameof(outputImage));
            }
            if (inputImage == outputImage)
            {
                throw new ArgumentException();
            }

            inputImage.ThrowIfDisposed(nameof(inputImage));
            outputImage.ThrowIfDisposed(nameof(outputImage));

            var inType  = inputImage.ImageType.ToNativeArray2DType();
            var outType = outputImage.ImageType.ToNativeArray2DType();
            var ret     = NativeMethods.resize_image2(inType, inputImage.NativePtr, outType, outputImage.NativePtr, interpolationTypes.ToNativeInterpolationTypes());

            switch (ret)
            {
            case NativeMethods.ErrorType.Array2DTypeTypeNotSupport:
                throw new ArgumentException("Output or input type is not supported.");
            }
        }
示例#3
0
        public Matrix(Array2DBase array)
        {
            if (array == null)
            {
                throw new ArgumentNullException(nameof(array));
            }

            array.ThrowIfDisposed();

            if (!TryParse(typeof(TElement), out var type))
            {
                throw new NotSupportedException($"{typeof(TElement).Name} does not support");
            }

            this._MatrixElementTypes = type;
            this._ElementType        = type.ToNativeMatrixElementType();
            var ret = NativeMethods.mat_matrix(array.ImageType.ToNativeArray2DType(),
                                               array.NativePtr,
                                               0,
                                               0,
                                               this._ElementType,
                                               out var ptr);

            switch (ret)
            {
            case NativeMethods.ErrorType.MatrixElementTypeNotSupport:
                throw new ArgumentException($"{array.ImageType} can not convert to {type}.");
            }

            this.NativePtr = ptr;
            this._Indexer  = this.CreateIndexer(type);
        }
示例#4
0
        public static void DrawLine(Array2DBase image, Point p1, Point p2, float color)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }
            if (p1 == null)
            {
                throw new ArgumentNullException(nameof(p1));
            }
            if (p2 == null)
            {
                throw new ArgumentNullException(nameof(p2));
            }

            image.ThrowIfDisposed();

            using (var np1 = p1.ToNative())
                using (var np2 = p2.ToNative())
                {
                    var ret = Native.draw_line(
                        Native.Array2DType.Float,
                        image.NativePtr,
                        np1.NativePtr,
                        np2.NativePtr,
                        ref color);
                    switch (ret)
                    {
                    case Native.ErrorType.ArrayTypeNotSupport:
                        throw new ArgumentException($"{color} is not supported.");
                    }
                }
        }
示例#5
0
        public static void SumFilter(Array2DBase inImage, Array2DBase outImage, Rectangle rect)
        {
            if (inImage == null)
            {
                throw new ArgumentNullException(nameof(inImage));
            }
            if (outImage == null)
            {
                throw new ArgumentNullException(nameof(outImage));
            }

            inImage.ThrowIfDisposed(nameof(inImage));
            outImage.ThrowIfDisposed(nameof(outImage));

            if (inImage.Rows != outImage.Rows || inImage.Columns != outImage.Columns)
            {
                throw new ArgumentException();
            }

            var inType  = inImage.ImageType.ToNativeArray2DType();
            var outType = outImage.ImageType.ToNativeArray2DType();

            using (var native = rect.ToNative())
            {
                var ret = Native.sum_filter(inType, inImage.NativePtr, outType, outImage.NativePtr, native.NativePtr);
                switch (ret)
                {
                case Native.ErrorType.OutputArrayTypeNotSupport:
                    throw new ArgumentException($"Output {outImage.ImageType} is not supported.");

                case Native.ErrorType.InputArrayTypeNotSupport:
                    throw new ArgumentException($"Input {inImage.ImageType} is not supported.");
                }
            }
        }
示例#6
0
        public static void GaussianBlur(Array2DBase inImage, Array2DBase outImage, double sigma = 1, int maxSize = 1001)
        {
            if (inImage == null)
            {
                throw new ArgumentNullException(nameof(inImage));
            }
            if (outImage == null)
            {
                throw new ArgumentNullException(nameof(outImage));
            }
            if (!(sigma > 0))
            {
                throw new ArgumentOutOfRangeException(nameof(sigma));
            }
            if (!(0 < maxSize && maxSize % 2 != 0))
            {
                throw new ArgumentOutOfRangeException(nameof(maxSize));
            }

            inImage.ThrowIfDisposed(nameof(inImage));
            outImage.ThrowIfDisposed(nameof(outImage));

            var inType  = inImage.ImageType.ToNativeArray2DType();
            var outType = outImage.ImageType.ToNativeArray2DType();
            var ret     = Native.gaussian_blur(inType, inImage.NativePtr, outType, outImage.NativePtr, sigma, maxSize);

            switch (ret)
            {
            case Native.ErrorType.OutputArrayTypeNotSupport:
                throw new ArgumentException($"Output {outImage.ImageType} is not supported.");

            case Native.ErrorType.InputArrayTypeNotSupport:
                throw new ArgumentException($"Input {inImage.ImageType} is not supported.");
            }
        }
示例#7
0
        public Point GetBestHoughPoint(Array2DBase image, Point point)
        {
            this.ThrowIfDisposed();

            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }
            if (point == null)
            {
                throw new ArgumentNullException(nameof(point));
            }

            image.ThrowIfDisposed();

            var inType = image.ImageType.ToNativeArray2DType();

            using (var native = point.ToNative())
            {
                var ret = NativeMethods.hough_transform_get_best_hough_point(
                    this.NativePtr,
                    native.NativePtr,
                    inType,
                    image.NativePtr,
                    out var resultPoint);
                switch (ret)
                {
                case NativeMethods.ErrorType.Array2DTypeTypeNotSupport:
                    throw new ArgumentException($"Input {image.ImageType} is not supported.");
                }

                return(new Point(resultPoint));
            }
        }
示例#8
0
        public void Operator(Array2DBase inImage, Rectangle rect, Array2DBase outImage)
        {
            this.ThrowIfDisposed();

            if (inImage == null)
            {
                throw new ArgumentNullException(nameof(inImage));
            }
            if (outImage == null)
            {
                throw new ArgumentNullException(nameof(outImage));
            }

            inImage.ThrowIfDisposed();
            outImage.ThrowIfDisposed();

            var inType  = inImage.ImageType.ToNativeArray2DType();
            var outType = outImage.ImageType.ToNativeArray2DType();

            using (var native = rect.ToNative())
            {
                var ret = NativeMethods.hough_transform_operator(
                    this.NativePtr,
                    inType,
                    inImage.NativePtr,
                    outType,
                    outImage.NativePtr,
                    native.NativePtr);
                switch (ret)
                {
                case NativeMethods.ErrorType.Array2DTypeTypeNotSupport:
                    throw new ArgumentException("Output or input type is not supported.");
                }
            }
        }
示例#9
0
        public FullObjectDetection Detect(Array2DBase image, Rectangle rect)
        {
            this.ThrowIfDisposed();

            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            image.ThrowIfDisposed();

            var inType = image.ImageType.ToNativeArray2DType();

            using (var native = rect.ToNative())
            {
                var ret = Native.shape_predictor_operator(this.NativePtr, inType, image.NativePtr, native.NativePtr, out var fullObjDetect);
                switch (ret)
                {
                case Dlib.Native.ErrorType.Array2DTypeTypeNotSupport:
                    throw new ArgumentException($"Input {inType} is not supported.");
                }

                return(new FullObjectDetection(fullObjDetect));
            }
        }
示例#10
0
        public ImageWindow(Array2DBase image)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            image.ThrowIfDisposed(nameof(image));

            this.NativePtr = NativeMethods.image_window_new_array2d1(image.ImageType.ToNativeArray2DType(), image.NativePtr);
        }
示例#11
0
        public static void PyramidUp(Array2DBase image)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            image.ThrowIfDisposed(nameof(image));

            var array2DType = image.ImageType.ToNativeArray2DType();
            var ret         = NativeMethods.pyramid_up(array2DType, image.NativePtr);

            if (ret == NativeMethods.ErrorType.Array2DTypeTypeNotSupport)
            {
                throw new ArgumentException($"{image.ImageType} is not supported.");
            }
        }
示例#12
0
        public ImageWindow(Array2DBase image, string title)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }
            if (title == null)
            {
                throw new ArgumentNullException(nameof(title));
            }

            image.ThrowIfDisposed(nameof(image));

            var str = Dlib.Encoding.GetBytes(title);

            this.NativePtr = NativeMethods.image_window_new_array2d2(image.ImageType.ToNativeArray2DType(), image.NativePtr, str, str.Length);
        }
示例#13
0
        public static void EqualizeHistogram(Array2DBase image)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            image.ThrowIfDisposed();

            var elementType = image.ImageType.ToNativeArray2DType();
            var ret         = NativeMethods.equalize_histogram_array2d(elementType, image.NativePtr);

            switch (ret)
            {
            case NativeMethods.ErrorType.Array2DTypeTypeNotSupport:
                throw new ArgumentException($"{elementType} is not supported.");
            }
        }
示例#14
0
        public static void FlipImageLeftRight(Array2DBase image)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            image.ThrowIfDisposed(nameof(image));

            var array2DType = image.ImageType.ToNativeArray2DType();
            var ret         = NativeMethods.flip_image_left_right(array2DType, image.NativePtr);

            switch (ret)
            {
            case NativeMethods.ErrorType.Array2DTypeTypeNotSupport:
                throw new ArgumentException($"{image.ImageType} is not supported.");
            }
        }
示例#15
0
        public static Array <Array2D <T> > ExtracFHogFeaturesArray <T>(Array2DBase inImage, int cellSize = 8, int filterRowsPadding = 1, int filterColsPadding = 1)
            where T : struct
        {
            if (inImage == null)
            {
                throw new ArgumentNullException(nameof(inImage));
            }
            if (!(cellSize > 0))
            {
                throw new ArgumentOutOfRangeException(nameof(cellSize));
            }
            if (!(filterRowsPadding > 0))
            {
                throw new ArgumentOutOfRangeException(nameof(filterRowsPadding));
            }
            if (!(filterColsPadding > 0))
            {
                throw new ArgumentOutOfRangeException(nameof(filterColsPadding));
            }

            inImage.ThrowIfDisposed(nameof(inImage));

            var hogImage = new Array <Array2D <T> >();

            if (!Array2D <T> .TryParse <T>(out var type))
            {
                throw new NotSupportedException();
            }

            var inType  = inImage.ImageType.ToNativeArray2DType();
            var outType = type.ToNativeArray2DType();
            var ret     = Native.extract_fhog_features_array(inType, inImage.NativePtr, outType, hogImage.NativePtr, cellSize, filterRowsPadding, filterColsPadding);

            switch (ret)
            {
            case Native.ErrorType.OutputElementTypeNotSupport:
                throw new ArgumentException($"Output {outType} is not supported.");

            case Native.ErrorType.InputArrayTypeNotSupport:
                throw new ArgumentException($"Input {inImage.ImageType} is not supported.");
            }

            return(hogImage);
        }
示例#16
0
        public void SetImage(Array2DBase image)
        {
            this.ThrowIfDisposed();

            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            image.ThrowIfDisposed();

            var ret = NativeMethods.image_window_set_image_array2d(this.NativePtr, image.ImageType.ToNativeArray2DType(), image.NativePtr);

            switch (ret)
            {
            case NativeMethods.ErrorType.Array2DTypeTypeNotSupport:
                throw new ArgumentException($"{image.ImageType} is not supported.");
            }
        }
示例#17
0
文件: MatrixMat.cs 项目: TrojanOlx/AI
        public static MatrixOp Mat(Array2DBase array)
        {
            if (array == null)
            {
                throw new ArgumentNullException(nameof(array));
            }

            array.ThrowIfDisposed();

            var imageType = array.ImageType.ToNativeArray2DType();
            var ret       = NativeMethods.mat_array2d(imageType, array.NativePtr, out var matrix);

            switch (ret)
            {
            case ErrorType.Array2DTypeTypeNotSupport:
                throw new ArgumentException($"{imageType} is not supported.");
            }

            return(new MatrixOp(ElementType.OpArray2DToMat, array.ImageType, matrix));
        }
示例#18
0
        public static Array2D <T> ExtractImageChip <T>(Array2DBase image, ChipDetails chipLocation, InterpolationTypes type = InterpolationTypes.NearestNeighbor)
            where T : struct
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }
            if (chipLocation == null)
            {
                throw new ArgumentNullException(nameof(chipLocation));
            }

            image.ThrowIfDisposed();
            chipLocation.ThrowIfDisposed();

            if (!chipLocation.IsValid())
            {
                throw new ArgumentException($"{nameof(chipLocation)} is invalid item.");
            }

            var chip        = new Array2D <T>();
            var array2DType = image.ImageType.ToNativeArray2DType();
            var ret         = Native.extract_image_chip2(array2DType,
                                                         image.NativePtr,
                                                         chipLocation.NativePtr,
                                                         chip.ImageType.ToNativeArray2DType(),
                                                         type.ToNativeInterpolationTypes(),
                                                         chip.NativePtr);

            switch (ret)
            {
            case Native.ErrorType.InputArrayTypeNotSupport:
                throw new ArgumentException($"{image.ImageType} is not supported.");

            case Native.ErrorType.OutputArrayTypeNotSupport:
                throw new ArgumentException($"{chip.ImageType} is not supported.");
            }

            return(chip);
        }
示例#19
0
        public void Operator(Array2DBase inImage, Rectangle rect, Array2DBase outImage)
        {
            this.ThrowIfDisposed();

            if (inImage == null)
            {
                throw new ArgumentNullException(nameof(inImage));
            }
            if (rect == null)
            {
                throw new ArgumentNullException(nameof(rect));
            }
            if (outImage == null)
            {
                throw new ArgumentNullException(nameof(outImage));
            }

            inImage.ThrowIfDisposed();
            rect.ThrowIfDisposed();
            outImage.ThrowIfDisposed();

            var inType  = inImage.ImageType.ToNativeArray2DType();
            var outType = outImage.ImageType.ToNativeArray2DType();
            var ret     = Native.hough_transform_operator(
                this.NativePtr,
                inType,
                inImage.NativePtr,
                outType,
                outImage.NativePtr,
                rect.NativePtr);

            switch (ret)
            {
            case Dlib.Native.ErrorType.OutputArrayTypeNotSupport:
                throw new ArgumentException($"Output {outImage.ImageType} is not supported.");

            case Dlib.Native.ErrorType.InputArrayTypeNotSupport:
                throw new ArgumentException($"Input {inImage.ImageType} is not supported.");
            }
        }
示例#20
0
        public static Array2DMatrix <T> ExtractFHogFeatures <T>(Array2DBase inImage, int cellSize = 8, int filterRowsPadding = 1, int filterColsPadding = 1)
            where T : struct
        {
            if (inImage == null)
            {
                throw new ArgumentNullException(nameof(inImage));
            }
            if (!(cellSize > 0))
            {
                throw new ArgumentOutOfRangeException(nameof(cellSize));
            }
            if (!(filterRowsPadding > 0))
            {
                throw new ArgumentOutOfRangeException(nameof(filterRowsPadding));
            }
            if (!(filterColsPadding > 0))
            {
                throw new ArgumentOutOfRangeException(nameof(filterColsPadding));
            }

            inImage.ThrowIfDisposed(nameof(inImage));

            //var hogImage = new FHogArray2DMatrix<T>();
            var hogImage = new Array2DMatrix <T>(0, 0, 31, 1);

            var inType  = inImage.ImageType.ToNativeArray2DType();
            var outType = hogImage.MatrixElementType.ToNativeMatrixElementType();
            var ret     = NativeMethods.extract_fhog_features(inType, inImage.NativePtr, outType, hogImage.NativePtr, cellSize, filterRowsPadding, filterColsPadding);

            switch (ret)
            {
            case NativeMethods.ErrorType.MatrixElementTypeNotSupport:
                throw new ArgumentException($"Output {outType} is not supported.");

            case NativeMethods.ErrorType.Array2DTypeTypeNotSupport:
                throw new ArgumentException($"Input {inImage.ImageType} is not supported.");
            }

            return(hogImage);
        }
示例#21
0
        public static Array <Array2D <T> > ExtractImageChips <T>(Array2DBase image, IEnumerable <ChipDetails> chipLocations)
            where T : struct
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }
            if (chipLocations == null)
            {
                throw new ArgumentNullException(nameof(chipLocations));
            }
            if (chipLocations.Any(chip => chip == null || chip.IsDisposed || !chip.IsValid()))
            {
                throw new ArgumentException($"{nameof(chipLocations)} includes invalid item.");
            }

            image.ThrowIfDisposed();

            using (var vectorOfChips = new StdVector <ChipDetails>(chipLocations))
            {
                var array       = new Array <Array2D <T> >();
                var array2DType = image.ImageType.ToNativeArray2DType();
                var ret         = Native.extract_image_chips(array2DType,
                                                             image.NativePtr,
                                                             vectorOfChips.NativePtr,
                                                             array.ImageType.ToNativeArray2DType(),
                                                             array.NativePtr);
                switch (ret)
                {
                case Native.ErrorType.InputArrayTypeNotSupport:
                    throw new ArgumentException($"{image.ImageType} is not supported.");

                case Native.ErrorType.OutputArrayTypeNotSupport:
                    throw new ArgumentException($"{array.ImageType} is not supported.");
                }

                return(array);
            }
        }
示例#22
0
        public static void ResizeImage(Array2DBase inputImage, double scale)
        {
            if (inputImage == null)
            {
                throw new ArgumentNullException(nameof(inputImage));
            }
            if (scale <= 0)
            {
                throw new ArgumentException($"{nameof(scale)} is less than or equal to zero.", nameof(scale));
            }

            inputImage.ThrowIfDisposed(nameof(inputImage));

            var inType = inputImage.ImageType.ToNativeArray2DType();
            var ret    = NativeMethods.resize_image3(inType, inputImage.NativePtr, scale);

            switch (ret)
            {
            case NativeMethods.ErrorType.Array2DTypeTypeNotSupport:
                throw new ArgumentException($"{inputImage.ImageType} is not supported.");
            }
        }
示例#23
0
        public double UpdateNoscale(Array2DBase image)
        {
            this.ThrowIfDisposed();

            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            image.ThrowIfDisposed();

            var inType = image.ImageType.ToNativeArray2DType();
            var ret    = Native.correlation_tracker_update_noscale2(this.NativePtr, inType, image.NativePtr, out var confident);

            switch (ret)
            {
            case Dlib.Native.ErrorType.InputArrayTypeNotSupport:
                throw new ArgumentException($"Input {inType} is not supported.");
            }

            return(confident);
        }
示例#24
0
        public static void TransformImage(Array2DBase inputImage, Array2DBase outputImage, PointTransformBase pointTransform, InterpolationTypes interpolationTypes = InterpolationTypes.Quadratic)
        {
            if (inputImage == null)
            {
                throw new ArgumentNullException(nameof(inputImage));
            }
            if (outputImage == null)
            {
                throw new ArgumentNullException(nameof(outputImage));
            }
            if (pointTransform == null)
            {
                throw new ArgumentNullException(nameof(pointTransform));
            }
            if (inputImage == outputImage)
            {
                throw new ArgumentException();
            }

            inputImage.ThrowIfDisposed(nameof(inputImage));
            outputImage.ThrowIfDisposed(nameof(outputImage));

            var inType  = inputImage.ImageType.ToNativeArray2DType();
            var outType = outputImage.ImageType.ToNativeArray2DType();
            var ret     = NativeMethods.transform_image(inType,
                                                        inputImage.NativePtr,
                                                        outType,
                                                        outputImage.NativePtr,
                                                        pointTransform.GetNativePointMappingTypes(),
                                                        pointTransform.NativePtr,
                                                        interpolationTypes.ToNativeInterpolationTypes());

            switch (ret)
            {
            case NativeMethods.ErrorType.Array2DTypeTypeNotSupport:
                throw new ArgumentException("Output or input type is not supported.");
            }
        }
示例#25
0
        public static void DrawRectangle(Array2DBase image, Rectangle rect, HsiPixel color, uint thickness = 1)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            image.ThrowIfDisposed();

            using (var native = rect.ToNative())
            {
                var ret = NativeMethods.draw_rectangle(NativeMethods.Array2DType.HsiPixel,
                                                       image.NativePtr,
                                                       native.NativePtr,
                                                       ref color,
                                                       thickness);
                switch (ret)
                {
                case NativeMethods.ErrorType.Array2DTypeTypeNotSupport:
                    throw new ArgumentException($"{color} is not supported.");
                }
            }
        }
示例#26
0
        public static void AssignImage(Array2DBase src, Array2DBase dest)
        {
            if (src == null)
            {
                throw new ArgumentNullException(nameof(src));
            }
            if (dest == null)
            {
                throw new ArgumentNullException(nameof(dest));
            }

            src.ThrowIfDisposed(nameof(src));
            dest.ThrowIfDisposed(nameof(dest));

            var inType  = src.ImageType.ToNativeArray2DType();
            var outType = dest.ImageType.ToNativeArray2DType();
            var ret     = Native.assign_image(outType, dest.NativePtr, inType, src.NativePtr);

            switch (ret)
            {
            case Native.ErrorType.Array2DTypeTypeNotSupport:
                throw new ArgumentException("Output or input type is not supported.");
            }
        }
示例#27
0
        public Rectangle[] Operator(Array2DBase image, double threshold = 0d)
        {
            this.ThrowIfDisposed();

            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            image.ThrowIfDisposed();

            using (var dets = new StdVector <Rectangle>())
            {
                var inType = image.ImageType.ToNativeArray2DType();
                var ret    = Native.frontal_face_detector_operator(this.NativePtr, inType, image.NativePtr, threshold, dets.NativePtr);
                switch (ret)
                {
                case Dlib.Native.ErrorType.InputArrayTypeNotSupport:
                    throw new ArgumentException($"Input {inType} is not supported.");
                }

                return(dets.ToArray());
            }
        }
示例#28
0
        /// <summary>
        /// This function saves image to disk as JPEG (Joint Photographic Experts Group) file.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="path">A string that contains the name of the file to which to save image.</param>
        /// <param name="quality">The quality of file. It must be 0 - 100. The default value is 75.</param>
        /// <exception cref="ArgumentException">The specified type of image is not supported.</exception>
        /// <exception cref="ArgumentException"><see cref="TwoDimensionObjectBase.Rows"/> or <see cref="TwoDimensionObjectBase.Columns"/> are less than or equal to zero.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="image"/> or <paramref name="path"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="quality"/> is less than zero or greater than 100.</exception>
        /// <exception cref="ObjectDisposedException"><paramref name="image"/> is disposed.</exception>
        public static void SaveJpeg(Array2DBase image, string path, int quality = 75)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            image.ThrowIfDisposed();

            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }
            if (image.Rows <= 0 || image.Columns <= 0)
            {
                throw new ArgumentException($"{nameof(image.Columns)} and {nameof(image.Rows)} is less than or equal to zero.", nameof(image));
            }
            if (quality < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(quality), $"{nameof(quality)} is less than zero.");
            }
            if (quality > 100)
            {
                throw new ArgumentOutOfRangeException(nameof(quality), $"{nameof(quality)} is greater than 100.");
            }

            var str = Encoding.GetBytes(path);

            var array2DType = image.ImageType.ToNativeArray2DType();
            var ret         = NativeMethods.save_jpeg(array2DType, image.NativePtr, str, quality);

            if (ret == NativeMethods.ErrorType.Array2DTypeTypeNotSupport)
            {
                throw new ArgumentException($"{image.ImageType} is not supported.");
            }
        }