VintaSoft Imaging .NET SDK 14.0: Документация для .NET разработчика
В этом разделе
    Пользовательская команда обработки изображения
    В этом разделе
    Для создания пользовательской команды обработки изображения необходимо выполнить следующие действия:
    1. Создать новый класс, который наследуется от класса ProcessingCommandBase или любой другой существующей команды обработки изображений из пространства имен Vintasoft.Imaging.ImageProcessing
    2. Переопределить метод ProcessingCommandBase.ProcessImageInPlace в своем классе
    3. Переопределить свойство ProcessingCommandBase.SupportedPixelFormats, если ваша команда поддерживает не все форматы пикселей
    4. Вызвать метод ProcessingCommandBase.RaiseProgress во время выполнения команды, если ваша команда поддерживает индикатор прогресса


    Вот C#/VB.NET код, который демонстрирует, как создать команду обработки изображения, которая инвертирует цвета изображения:
    /// <summary>
    /// Inverts colors of an image.
    /// </summary>
    public class CustomInvertCommand : Vintasoft.Imaging.ImageProcessing.ProcessingCommandWithRegion
    {
    
        #region Constructors
    
        /// <summary>
        /// Initializes a new instance of the  class.
        /// </summary>
        public CustomInvertCommand()
            : base()
        {
        }
    
        #endregion
    
    
    
        #region Properties
    
        /// <summary>
        /// Gets the name of the command.
        /// </summary>
        public override string Name
        {
            get
            {
                return "Invert";
            }
        }
    
        /// <summary>
        /// Gets a list of supported native pixel formats for this processing command.
        /// </summary>
        public override System.Collections.ObjectModel.ReadOnlyCollection<Vintasoft.Imaging.PixelFormat> SupportedNativePixelFormats
        {
            get
            {
                System.Collections.Generic.List<Vintasoft.Imaging.PixelFormat> supportedNativePixelFormats =
                    new System.Collections.Generic.List<Vintasoft.Imaging.PixelFormat>();
                supportedNativePixelFormats.Add(Vintasoft.Imaging.PixelFormat.BlackWhite);
                supportedNativePixelFormats.Add(Vintasoft.Imaging.PixelFormat.Indexed1);
                supportedNativePixelFormats.Add(Vintasoft.Imaging.PixelFormat.Indexed4);
                supportedNativePixelFormats.Add(Vintasoft.Imaging.PixelFormat.Indexed8);
                supportedNativePixelFormats.Add(Vintasoft.Imaging.PixelFormat.Gray8);
                supportedNativePixelFormats.Add(Vintasoft.Imaging.PixelFormat.Gray16);
                supportedNativePixelFormats.Add(Vintasoft.Imaging.PixelFormat.Bgr24);
                supportedNativePixelFormats.Add(Vintasoft.Imaging.PixelFormat.Bgr32);
                supportedNativePixelFormats.Add(Vintasoft.Imaging.PixelFormat.Bgr48);
                supportedNativePixelFormats.Add(Vintasoft.Imaging.PixelFormat.Bgra32);
                supportedNativePixelFormats.Add(Vintasoft.Imaging.PixelFormat.Bgra64);
                return supportedNativePixelFormats.AsReadOnly();
            }
        }
    
        #endregion
    
    
    
        #region Methods
    
        /// <summary>
        /// Returns the pixel format of output image (image after processing)
        /// for input image with specified pixel format.
        /// </summary>
        /// <param name="inputPixelFormat">Pixel format of input image.</param>
        /// <returns>Pixel format of output image.</returns>
        public override Vintasoft.Imaging.PixelFormat GetOutputPixelFormat(
            Vintasoft.Imaging.PixelFormat inputPixelFormat)
        {
            if (IsPixelFormatSupported(inputPixelFormat))
                return inputPixelFormat;
            return Vintasoft.Imaging.PixelFormat.Undefined;
        }
    
        /// <summary>
        /// Creates a new <see cref="CustomInvertCommand"/> that is a copy of the current
        /// instance.
        /// </summary>
        /// <returns>A new <see cref="CustomInvertCommand"/> that is a copy of this
        /// instance.</returns>
        public override object Clone()
        {
            return new CustomInvertCommand();
        }
    
        /// <summary>
        /// Processes the image in-place.
        /// </summary>
        /// <param name="image">Image to process.</param>
        /// <returns>
        /// <b>true</b> if image is processed;
        /// <b>false</b> if processing is canceled or not necessary.
        /// </returns>
        /// <remarks>
        /// This method changes the <i>image</i>.
        /// </remarks>
        protected override bool ProcessImageInPlace(Vintasoft.Imaging.VintasoftImage image)
        {
            System.Drawing.Rectangle rect = this.GetSafeRegionOfInterest(image);
    
            bool cancel = false;
    
            int height = rect.Height;
    
            Vintasoft.Imaging.PixelManipulator pixelManipulator;
            byte[] rowData;
            int rowLength;
    
            float progress = 0;
            float progressDelta = 100f / height;
    
            switch (image.PixelFormat)
            {
                case Vintasoft.Imaging.PixelFormat.BlackWhite:
                case Vintasoft.Imaging.PixelFormat.Indexed1:
                case Vintasoft.Imaging.PixelFormat.Indexed4:
                case Vintasoft.Imaging.PixelFormat.Indexed8:
                case Vintasoft.Imaging.PixelFormat.Gray8:
                    if (!RegionOfInterest.IsEmpty)
                        throw new Vintasoft.Imaging.ImageProcessing.ImageProcessingException(
                            string.Format("{0}: this processing command does not support RegionOfInterest for palette images.", Name));
    
                    image.Palette.Invert();
                    break;
    
                case Vintasoft.Imaging.PixelFormat.Gray16:
                    pixelManipulator = image.OpenPixelManipulator();
                    pixelManipulator.LockPixels(rect, Vintasoft.Imaging.BitmapLockMode.ReadWrite);
                    rowLength = rect.Width * 2;
                    rowData = new byte[rowLength];
                    for (int y = 0; y < height; y++)
                    {
                        pixelManipulator.ReadRowDataUnsafe(y, rowData, 0, rowLength);
                        for (int x = 0; x < rowLength; x += 2)
                        {
                            rowData[x] ^= 0xFF;
                            rowData[x + 1] ^= 0x3F;
                        }
                        pixelManipulator.WriteRowData(y, rowData, 0, rowLength);
    
                        // change the progress
                        progress += progressDelta;
                        // raise the progress event
                        if (!RaiseProgress(progress, true))
                        {
                            cancel = true;
                            break;
                        }
                    }
                    pixelManipulator.UnlockPixels();
                    // close the pixel manipulator
                    image.ClosePixelManipulator(true);
                    break;
    
                case Vintasoft.Imaging.PixelFormat.Bgr24:
                case Vintasoft.Imaging.PixelFormat.Bgr48:
                    pixelManipulator = image.OpenPixelManipulator();
                    pixelManipulator.LockPixels(rect, Vintasoft.Imaging.BitmapLockMode.ReadWrite);
                    rowLength = rect.Width * 3;
                    rowData = new byte[rowLength];
                    for (int y = 0; y < height; y++)
                    {
                        pixelManipulator.ReadRowDataUnsafe(y, rowData, 0, rowLength);
                        for (int x = 0; x < rowLength; x++)
                        {
                            rowData[x] ^= 0xFF;
                        }
                        pixelManipulator.WriteRowDataUnsafe(y, rowData, 0, rowLength);
    
                        // change the progress
                        progress += progressDelta;
                        // raise the progress event
                        if (!RaiseProgress(progress, true))
                        {
                            cancel = true;
                            break;
                        }
                    }
                    pixelManipulator.UnlockPixels();
                    // close the pixel manipulator
                    image.ClosePixelManipulator(true);
                    break;
    
                case Vintasoft.Imaging.PixelFormat.Bgr32:
                case Vintasoft.Imaging.PixelFormat.Bgra32:
                case Vintasoft.Imaging.PixelFormat.Bgra64:
                    pixelManipulator = image.OpenPixelManipulator();
                    pixelManipulator.LockPixels(rect, Vintasoft.Imaging.BitmapLockMode.ReadWrite);
                    rowLength = rect.Width * 4;
                    rowData = new byte[rowLength];
                    for (int y = 0; y < height; y++)
                    {
                        pixelManipulator.ReadRowDataUnsafe(y, rowData, 0, rowLength);
                        for (int x = 0; x < rowLength; x += 4)
                        {
                            rowData[x] ^= 0xFF;
                            rowData[x + 1] ^= 0xFF;
                            rowData[x + 2] ^= 0xFF;
                        }
                        pixelManipulator.WriteRowDataUnsafe(y, rowData, 0, rowLength);
    
                        // change the progress
                        progress += progressDelta;
                        // raise the progress event
                        if (!RaiseProgress(progress, true))
                        {
                            cancel = true;
                            break;
                        }
                    }
                    pixelManipulator.UnlockPixels();
                    // close the pixel manipulator
                    image.ClosePixelManipulator(true);
                    break;
            }
    
            return !cancel;
        }
    
        #endregion
    
    }
    
    ''' <summary>
    ''' Inverts colors of an image.
    ''' </summary>
    Public Class CustomInvertCommand
        Inherits Vintasoft.Imaging.ImageProcessing.ProcessingCommandWithRegion
    
        #Region "Constructors"
    
        ''' <summary>
        ''' Initializes a new instance of the  class.
        ''' </summary>
        Public Sub New()
            MyBase.New()
        End Sub
    
        #End Region
    
    
    
        #Region "Properties"
    
        ''' <summary>
        ''' Gets the name of the command.
        ''' </summary>
        Public Overrides ReadOnly Property Name() As String
            Get
                Return "Invert"
            End Get
        End Property
    
        ''' <summary>
        ''' Gets a list of supported native pixel formats for this processing command.
        ''' </summary>
        Public Overrides ReadOnly Property SupportedNativePixelFormats() As System.Collections.ObjectModel.ReadOnlyCollection(Of Vintasoft.Imaging.PixelFormat)
            Get
                Dim supportedNativePixelFormats__1 As New System.Collections.Generic.List(Of Vintasoft.Imaging.PixelFormat)()
                supportedNativePixelFormats__1.Add(Vintasoft.Imaging.PixelFormat.BlackWhite)
                supportedNativePixelFormats__1.Add(Vintasoft.Imaging.PixelFormat.Indexed1)
                supportedNativePixelFormats__1.Add(Vintasoft.Imaging.PixelFormat.Indexed4)
                supportedNativePixelFormats__1.Add(Vintasoft.Imaging.PixelFormat.Indexed8)
                supportedNativePixelFormats__1.Add(Vintasoft.Imaging.PixelFormat.Gray8)
                supportedNativePixelFormats__1.Add(Vintasoft.Imaging.PixelFormat.Gray16)
                supportedNativePixelFormats__1.Add(Vintasoft.Imaging.PixelFormat.Bgr24)
                supportedNativePixelFormats__1.Add(Vintasoft.Imaging.PixelFormat.Bgr32)
                supportedNativePixelFormats__1.Add(Vintasoft.Imaging.PixelFormat.Bgr48)
                supportedNativePixelFormats__1.Add(Vintasoft.Imaging.PixelFormat.Bgra32)
                supportedNativePixelFormats__1.Add(Vintasoft.Imaging.PixelFormat.Bgra64)
                Return supportedNativePixelFormats__1.AsReadOnly()
            End Get
        End Property
    
        #End Region
    
    
    
        #Region "Methods"
    
        ''' <summary>
        ''' Returns the pixel format of output image (image after processing)
        ''' for input image with specified pixel format.
        ''' </summary>
        ''' <param name="inputPixelFormat">Pixel format of input image.</param>
        ''' <returns>Pixel format of output image.</returns>
        Public Overrides Function GetOutputPixelFormat(inputPixelFormat As Vintasoft.Imaging.PixelFormat) As Vintasoft.Imaging.PixelFormat
            If IsPixelFormatSupported(inputPixelFormat) Then
                Return inputPixelFormat
            End If
            Return Vintasoft.Imaging.PixelFormat.Undefined
        End Function
    
        ''' <summary>
        ''' Creates a new <see cref="CustomInvertCommand"/> that is a copy of the current
        ''' instance.
        ''' </summary>
        ''' <returns>A new <see cref="CustomInvertCommand"/> that is a copy of this
        ''' instance.</returns>
        Public Overrides Function Clone() As Object
            Return New CustomInvertCommand()
        End Function
    
        ''' <summary>
        ''' Processes the image in-place.
        ''' </summary>
        ''' <param name="image">Image to process.</param>
        ''' <returns>
        ''' <b>true</b> if image is processed;
        ''' <b>false</b> if processing is canceled or not necessary.
        ''' </returns>
        ''' <remarks>
        ''' This method changes the <i>image</i>.
        ''' </remarks>
        Protected Overrides Function ProcessImageInPlace(image As Vintasoft.Imaging.VintasoftImage) As Boolean
            Dim rect As System.Drawing.Rectangle = Me.GetSafeRegionOfInterest(image)
    
            Dim cancel As Boolean = False
    
            Dim height As Integer = rect.Height
    
            Dim pixelManipulator As Vintasoft.Imaging.PixelManipulator
            Dim rowData As Byte()
            Dim rowLength As Integer
    
            Dim progress As Single = 0
            Dim progressDelta As Single = 100F / height
    
            Select Case image.PixelFormat
                Case Vintasoft.Imaging.PixelFormat.BlackWhite, Vintasoft.Imaging.PixelFormat.Indexed1, Vintasoft.Imaging.PixelFormat.Indexed4, Vintasoft.Imaging.PixelFormat.Indexed8, Vintasoft.Imaging.PixelFormat.Gray8
                    If Not RegionOfInterest.IsEmpty Then
                        Throw New Vintasoft.Imaging.ImageProcessing.ImageProcessingException(String.Format("{0}: this processing command does not support RegionOfInterest for palette images.", Name))
                    End If
    
                    image.Palette.Invert()
                    Exit Select
    
                Case Vintasoft.Imaging.PixelFormat.Gray16
                    pixelManipulator = image.OpenPixelManipulator()
                    pixelManipulator.LockPixels(rect, Vintasoft.Imaging.BitmapLockMode.ReadWrite)
                    rowLength = rect.Width * 2
                    rowData = New Byte(rowLength - 1) {}
                    For y As Integer = 0 To height - 1
                        pixelManipulator.ReadRowDataUnsafe(y, rowData, 0, rowLength)
                        For x As Integer = 0 To rowLength - 1 Step 2
                            rowData(x) = rowData(x) Xor &Hff
                            rowData(x + 1) = rowData(x + 1) Xor &H3f
                        Next
                        pixelManipulator.WriteRowData(y, rowData, 0, rowLength)
    
                        ' change the progress
                        progress += progressDelta
                        ' raise the progress event
                        If Not RaiseProgress(progress, True) Then
                            cancel = True
                            Exit For
                        End If
                    Next
                    pixelManipulator.UnlockPixels()
                    ' close the pixel manipulator
                    image.ClosePixelManipulator(True)
                    Exit Select
    
                Case Vintasoft.Imaging.PixelFormat.Bgr24, Vintasoft.Imaging.PixelFormat.Bgr48
                    pixelManipulator = image.OpenPixelManipulator()
                    pixelManipulator.LockPixels(rect, Vintasoft.Imaging.BitmapLockMode.ReadWrite)
                    rowLength = rect.Width * 3
                    rowData = New Byte(rowLength - 1) {}
                    For y As Integer = 0 To height - 1
                        pixelManipulator.ReadRowDataUnsafe(y, rowData, 0, rowLength)
                        For x As Integer = 0 To rowLength - 1
                            rowData(x) = rowData(x) Xor &Hff
                        Next
                        pixelManipulator.WriteRowDataUnsafe(y, rowData, 0, rowLength)
    
                        ' change the progress
                        progress += progressDelta
                        ' raise the progress event
                        If Not RaiseProgress(progress, True) Then
                            cancel = True
                            Exit For
                        End If
                    Next
                    pixelManipulator.UnlockPixels()
                    ' close the pixel manipulator
                    image.ClosePixelManipulator(True)
                    Exit Select
    
                Case Vintasoft.Imaging.PixelFormat.Bgr32, Vintasoft.Imaging.PixelFormat.Bgra32, Vintasoft.Imaging.PixelFormat.Bgra64
                    pixelManipulator = image.OpenPixelManipulator()
                    pixelManipulator.LockPixels(rect, Vintasoft.Imaging.BitmapLockMode.ReadWrite)
                    rowLength = rect.Width * 4
                    rowData = New Byte(rowLength - 1) {}
                    For y As Integer = 0 To height - 1
                        pixelManipulator.ReadRowDataUnsafe(y, rowData, 0, rowLength)
                        For x As Integer = 0 To rowLength - 1 Step 4
                            rowData(x) = rowData(x) Xor &Hff
                            rowData(x + 1) = rowData(x + 1) Xor &Hff
                            rowData(x + 2) = rowData(x + 2) Xor &Hff
                        Next
                        pixelManipulator.WriteRowDataUnsafe(y, rowData, 0, rowLength)
    
                        ' change the progress
                        progress += progressDelta
                        ' raise the progress event
                        If Not RaiseProgress(progress, True) Then
                            cancel = True
                            Exit For
                        End If
                    Next
                    pixelManipulator.UnlockPixels()
                    ' close the pixel manipulator
                    image.ClosePixelManipulator(True)
                    Exit Select
            End Select
    
            Return Not cancel
        End Function
    
        #End Region
    
    End Class