/// <summary> /// HSL to RGB image /// </summary> /// <param name="source">image source</param> /// <param name="dest">image destination</param> public void HslToRgb(IImage2DFloatRgbA source, IImage2DFloatRgbA dest) { if (source == null) throw new ArgumentNullException("source"); if (dest == null) throw new ArgumentNullException("dest"); if ((source.Width > dest.Width) || (source.Height > dest.Height)) throw new ArgumentException("Destination image (" + dest.Width + "x" + dest.Height + ") must have at least the same size as the source image (" + source.Width + "x" + source.Height + ")"); if (source.Normalized) { // use normalized kernel // TODO: HSL to RGB image (normalized) } else { // use normal kernel // TODO: HSL to RGB image } dest.Normalized = source.Normalized; }
/// <summary> /// RGB to HSL image /// </summary> /// <param name="source">image source</param> /// <param name="dest">image destination</param> public void RgbToHsl(IImage2DFloatRgbA source, IImage2DFloatRgbA dest) { if (source == null) throw new ArgumentNullException("source"); if (dest == null) throw new ArgumentNullException("dest"); if ((source.Width > dest.Width) || (source.Height > dest.Height)) throw new ArgumentException("Destination image (" + dest.Width + "x" + dest.Height + ") must have at least the same size as the source image (" + source.Width + "x" + source.Height + ")"); if (source.Normalized) { // use normalized kernel for (int i = 0, j = 0, length = source.HostBuffer.Length; i < length;) { Color color = Color.FromArgb((int)(source.HostBuffer[i++] * 255f), (int)(source.HostBuffer[i++] * 255f), (int)(source.HostBuffer[i++] * 255f)); dest.HostBuffer[j++] = color.GetHue() / 360f; dest.HostBuffer[j++] = color.GetSaturation(); dest.HostBuffer[j++] = color.GetBrightness(); dest.HostBuffer[j++] = source.HostBuffer[i++]; } } else { // use normal kernel for (int i = 0, j = 0, length = source.HostBuffer.Length; i < length; ) { Color color = Color.FromArgb((int)source.HostBuffer[i++], (int)source.HostBuffer[i++], (int)source.HostBuffer[i++]); dest.HostBuffer[j++] = color.GetHue() * 255f / 360f; dest.HostBuffer[j++] = color.GetSaturation() * 255f; dest.HostBuffer[j++] = color.GetBrightness() * 255f; dest.HostBuffer[j++] = source.HostBuffer[i++]; } } dest.Normalized = source.Normalized; }
/// <summary> /// GrayScale image /// </summary> /// <param name="source">image source</param> /// <param name="dest">image destination</param> public void GrayScale(IImage2DFloatRgbA source, IImage2DFloatA dest) { if (source == null) throw new ArgumentNullException("source"); if (dest == null) throw new ArgumentNullException("dest"); if ((source.Width > dest.Width) || (source.Height > dest.Height)) throw new ArgumentException("Destination image (" + dest.Width + "x" + dest.Height + ") must have at least the same size as the source image (" + source.Width + "x" + source.Height + ")"); int length = source.Width * source.Height; int pos = 0; for (int i = 0; i < length; i++) { float gray = 0.2989f * source.HostBuffer[pos++] + 0.5870f * source.HostBuffer[pos++] + 0.1140f * source.HostBuffer[pos++]; pos++; dest.HostBuffer[i] = gray; } dest.Normalized = source.Normalized; }
/// <summary> /// Flip image Y coordinate /// </summary> /// <param name="source">image source</param> /// <param name="dest">image destination</param> public void FlipY(IImage2DFloatRgbA source, IImage2DFloatRgbA dest) { if (source == null) throw new ArgumentNullException("source"); if (dest == null) throw new ArgumentNullException("dest"); if (source == dest) throw new ArgumentException("Flipping kernel is not designed to run inline therefore source and destination must be different images"); if ((source.Width > dest.Width) || (source.Height > dest.Height)) throw new ArgumentException("Destination image (" + dest.Width + "x" + dest.Height + ") must have at least the same size as the source image (" + source.Width + "x" + source.Height + ")"); var sBuf = source.HostBuffer; var dBuf = dest.HostBuffer; int posSource = 0; int posDest = 4 * (source.Height - 1) * dest.Width; for (int y = 0, h = source.Height; y < h; y++) { for (int x = 0, w = source.Width; x < w; x++) { float color; color = sBuf[posSource++]; dBuf[posDest++] = color; color = sBuf[posSource++]; dBuf[posDest++] = color; color = sBuf[posSource++]; dBuf[posDest++] = color; color = sBuf[posSource++]; dBuf[posDest++] = color; } posDest -= 4 * (dest.Width + source.Width); } }
/// <summary> /// Extracts a channel of an RGB image /// </summary> /// <param name="source">image source</param> /// <param name="dest">image destination</param> /// <param name="offset">offset (0..3)</param> public void ExtractChannel(IImage2DFloatRgbA source, IImage2DFloatA dest, byte offset) { if (source == null) throw new ArgumentNullException("source"); if (dest == null) throw new ArgumentNullException("dest"); if (offset > 3) throw new ArgumentOutOfRangeException("offset", String.Format("offset must be between 0..3 but was {0}", offset)); if ((source.Width > dest.Width) || (source.Height > dest.Height)) throw new ArgumentException("Destination image (" + dest.Width + "x" + dest.Height + ") must have at least the same size as the source image (" + source.Width + "x" + source.Height + ")"); int length = source.Width * source.Height; int pos = 0; for (int i = 0; i < length; i++) for (int j = 0; j < 4; j++) if (j == offset) dest.HostBuffer[i] = source.HostBuffer[pos++]; else pos++; dest.Normalized = source.Normalized; }
/// <summary> /// Box blur image /// </summary> /// <param name="source">image source</param> /// <param name="dest">image destination</param> /// <param name="sampler">sampler to be used for image reading</param> /// <param name="offset">offset</param> public void BoxBlur(IImage2DFloatRgbA source, IImage2DFloatRgbA dest, int offset) { if (source == null) throw new ArgumentNullException("source"); if (dest == null) throw new ArgumentNullException("dest"); if ((source.Width > dest.Width) || (source.Height > dest.Height)) throw new ArgumentException("Destination image (" + dest.Width + "x" + dest.Height + ") must have at least the same size as the source image (" + source.Width + "x" + source.Height + ")"); // TODO: Box blur image dest.Normalized = source.Normalized; }
/// <summary> /// Sets channel of a RGBA image /// </summary> /// <param name="source">source image</param> /// <param name="mask">mask image</param> /// <param name="dest">destination image</param> /// <param name="offset">offset (0..3)</param> public void SetChannel(IImage2DFloatRgbA source, IImage2DFloatA mask, IImage2DFloatRgbA dest, byte offset) { if (source == null) throw new ArgumentNullException("source"); if (mask == null) throw new ArgumentNullException("mask"); if (dest == null) throw new ArgumentNullException("dest"); if (offset > 3) throw new ArgumentOutOfRangeException("offset", String.Format("offset must be between 0..3 but was {0}", offset)); if ((source.Width > mask.Width) || (source.Height > mask.Height)) throw new ArgumentException("Image mask (" + dest.Width + "x" + dest.Height + ") must have at least the same size as the source image (" + source.Width + "x" + source.Height + ")"); if ((source.Width > dest.Width) || (source.Height > dest.Height)) throw new ArgumentException("Destination image (" + dest.Width + "x" + dest.Height + ") must have at least the same size as the source image (" + source.Width + "x" + source.Height + ")"); int length = source.Width * source.Height; int pos = 0; for (int i = 0; i < length; i++) for (int j = 0; j < 4; j++) { dest.HostBuffer[pos] = (j == offset) ? mask.HostBuffer[i] : source.HostBuffer[pos]; pos++; } }