/// <summary> /// Function to convert the pixel format of an image into another pixel format. /// </summary> /// <param name="baseImage">The image to convert.</param> /// <param name="format">The new pixel format for the image.</param> /// <param name="dithering">[Optional] Flag to indicate the type of dithering to perform when the bit depth for the <paramref name="format"/> is lower than the original bit depth.</param> /// <returns>A <see cref="IGorgonImage"/> containing the image data with the converted pixel format.</returns> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="baseImage"/> is <b>null</b>.</exception> /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="format"/> is set to <see cref="BufferFormat.Unknown"/>. /// <para>-or-</para> /// <para>Thrown when the original format could not be converted into the desired <paramref name="format"/>.</para> /// </exception> /// <remarks> /// <para> /// Use this to convert an image format from one to another. The conversion functionality uses Windows Imaging Components (WIC) to perform the conversion. /// </para> /// <para> /// Because this method uses WIC, not all formats will be convertible. To determine if a format can be converted, use the <see cref="GorgonImage.CanConvertToFormat"/> method. /// </para> /// <para> /// For the <see cref="BufferFormat.B4G4R4A4_UNorm"/> format, Gorgon has to perform a manual conversion since that format is not supported by WIC. Because of this, the /// <paramref name="dithering"/> flag will be ignored when downsampling to that format. /// </para> /// </remarks> public static IGorgonImage ConvertToFormat(this IGorgonImage baseImage, BufferFormat format, ImageDithering dithering = ImageDithering.None) { if (baseImage == null) { throw new ArgumentNullException(nameof(baseImage)); } if ((format == BufferFormat.Unknown) || (!baseImage.CanConvertToFormat(format))) { throw new ArgumentException(string.Format(Resources.GORIMG_ERR_FORMAT_NOT_SUPPORTED, format), nameof(format)); } if (format == baseImage.Format) { return(baseImage); } // If we've asked for 4 bit per channel BGRA, then we have to convert the base image to B8R8G8A8,and then convert manually (no support in WIC). if (format == BufferFormat.B4G4R4A4_UNorm) { return(ConvertToB4G4R4A4(baseImage, dithering)); } // If we're currently using B4G4R4A4, then manually convert (no support in WIC). if (baseImage.Format == BufferFormat.B4G4R4A4_UNorm) { return(ConvertFromB4G4R4A4(baseImage, format)); } var destInfo = new GorgonFormatInfo(format); WicUtilities wic = null; IGorgonImage newImage = null; try { wic = new WicUtilities(); newImage = wic.ConvertToFormat(baseImage, format, dithering, baseImage.FormatInfo.IsSRgb, destInfo.IsSRgb); newImage.CopyTo(baseImage); return(baseImage); } finally { newImage?.Dispose(); wic?.Dispose(); } }