The following steps must be made if the custom image processing command must be created:
' The project, which uses this code, must have references to the following assemblies: ' - Vintasoft.Imaging ''' <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
// The project, which uses this code, must have references to the following assemblies: // - Vintasoft.Imaging /// <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 }