/** * Splits a ColorBitmap into an RGBBitmap struct containing the * individual color componenets. The original ColorBitmap is left unmodified. * * @param fromColors The bitmap to split into channels. * @param toRGB RGBBitmap struct containing the channels for the ColorBitmap. */ public static void colorBitmapToRGBBitmap(ref ColorBitmap fromColors, ref RGBBitmap toRGB) { int channelLength = fromColors.colors.Length; string logString = string.Format("Converting bitmap to RGB (length {0})", channelLength); OnionLogger.globalLog.PushInfoLayer(logString); float[] r = new float[channelLength]; float[] g = new float[channelLength]; float[] b = new float[channelLength]; for (int i = 0; i < channelLength; ++i) { Color colorTuple = fromColors.colors[i]; r[i] = colorTuple.r; g[i] = colorTuple.g; b[i] = colorTuple.b; } RGBChannels rgb = new RGBChannels(); rgb.r = r; rgb.g = g; rgb.b = b; toRGB.rgb = rgb; toRGB.width = fromColors.width; toRGB.height = fromColors.height; OnionLogger.globalLog.PopInfoLayer(); }
/** * Extract a MonochromeBitmap from the blue channel of an RGBBitmap. * @param rgbBitmap The RGBBitmap to extract B from. * @return A MonochromeBitmap containing the blue channel. */ public static MonochromeBitmap blueBitmapFromRGBBitmap(ref RGBBitmap rgbBitmap) { MonochromeBitmap blue = new MonochromeBitmap(); blue.channel = rgbBitmap.rgb.b; blue.height = rgbBitmap.height; blue.width = rgbBitmap.width; return(blue); }
/** * Extract a MonochromeBitmap from the green channel of an RGBBitmap. * @param rgbBitmap The RGBBitmap to extract G from. * @return A MonochromeBitmap containing the green channel. */ public static MonochromeBitmap greenBitmapFromRGBBitmap(ref RGBBitmap rgbBitmap) { MonochromeBitmap green = new MonochromeBitmap(); green.channel = rgbBitmap.rgb.g; green.height = rgbBitmap.height; green.width = rgbBitmap.width; return(green); }
/** * Extract a MonochromeBitmap from the red channel of an RGBBitmap. * @param rgbBitmap The RGBBitmap to extract R from. * @return A MonochromeBitmap containing the red channel. */ public static MonochromeBitmap redBitmapFromRGBBitmap(ref RGBBitmap rgbBitmap) { MonochromeBitmap red = new MonochromeBitmap(); red.channel = rgbBitmap.rgb.r; red.height = rgbBitmap.height; red.width = rgbBitmap.width; return(red); }
/** * Joins an RGBBitmap struct containing individual color components into a single * bitmap (array of UnityEngine.Color). The RGBBitmap is left unchanged. * * @param fromRGB The RGB data to join into a ColorBitmap. * @param toColors A ColorBitmap equivalent to the rgb data. */ public static void RGBBitmapToColorBitmap(ref RGBBitmap fromRGB, ref ColorBitmap toColors) { int channelLength = fromRGB.rgb.r.Length; string logString = string.Format("Converting RGBBitmap to ColorBitmap (length {0})", channelLength); OnionLogger.globalLog.PushInfoLayer(logString); toColors.colors = new Color[channelLength]; toColors.width = fromRGB.width; toColors.height = fromRGB.height; for (int i = 0; i < channelLength; ++i) { toColors.colors[i] = new Color(fromRGB.rgb.r[i], fromRGB.rgb.g[i], fromRGB.rgb.b[i]); } OnionLogger.globalLog.PopInfoLayer(); }
/** * Applies gaussian blur effect to a grayscale bitmap. * @param colorBitmap the image to be processed. */ public void ProcessBitmap(ref ColorBitmap colorBitmap) { OnionLogger.globalLog.PushInfoLayer("Performing GrayscaleGaussianBlur on bitmap."); RGBBitmap rgbBitmap = new RGBBitmap(); ColorUtils.colorBitmapToRGBBitmap(ref colorBitmap, ref rgbBitmap); /* Since we are assuming the image is grayscale, we can apply the blur to just one * channel. We arbitrarily choose the red channel. */ MonochromeBitmap blurR = ColorUtils.redBitmapFromRGBBitmap(ref rgbBitmap); // temporarily hard-coded int numberOfCoefficients = 5; this.coefficients = ApproximateGaussianCoefficients(numberOfCoefficients); OnionLogger.globalLog.PushInfoLayer("Blurring rows"); ExecuteHorizontalBlur(ref blurR); ColorUtils.Transpose(ref blurR); /* transpose to set up for blurring columns */ OnionLogger.globalLog.PopInfoLayer(); // Since we transposed the image, we can re-use the horizontal blur operation to blur the columns. OnionLogger.globalLog.PushInfoLayer("Blurring columns"); ExecuteHorizontalBlur(ref blurR); ColorUtils.Transpose(ref blurR); /* reset the image to original orientation */ OnionLogger.globalLog.PopInfoLayer(); // Since we assumed that we are using a grayscale image, the Blue and Green channels can be copied from // the red channel. rgbBitmap.rgb.r = blurR.channel; rgbBitmap.rgb.b = blurR.channel; rgbBitmap.rgb.g = blurR.channel; ColorUtils.RGBBitmapToColorBitmap(ref rgbBitmap, ref colorBitmap); OnionLogger.globalLog.PopInfoLayer(); }
/** * Invert the colors of a bitmap. * * @param colorBitmap The ColorBitmap to invert. */ public void ProcessBitmap(ref ColorBitmap colorBitmap) { OnionLogger.globalLog.PushInfoLayer("Inverting bitmap"); RGBBitmap rgbBitmap = new RGBBitmap(); ColorUtils.colorBitmapToRGBBitmap(ref colorBitmap, ref rgbBitmap); MonochromeBitmap invertedr = ColorUtils.redBitmapFromRGBBitmap(ref rgbBitmap); MonochromeBitmap invertedg = ColorUtils.greenBitmapFromRGBBitmap(ref rgbBitmap); MonochromeBitmap invertedb = ColorUtils.blueBitmapFromRGBBitmap(ref rgbBitmap); // We'll run a thread for each color channel. int numberOfThreads = 3; ManualResetEvent[] threadsDone = new ManualResetEvent[numberOfThreads]; ColorInvertThread[] threads = new ColorInvertThread[numberOfThreads]; for (int i = 0; i < numberOfThreads; ++i) { threadsDone[i] = new ManualResetEvent(false); threads[i] = new ColorInvertThread(threadsDone[i]); } ThreadPool.QueueUserWorkItem(new WaitCallback(threads[0].ThreadedProcessChannel), invertedr); ThreadPool.QueueUserWorkItem(new WaitCallback(threads[1].ThreadedProcessChannel), invertedg); ThreadPool.QueueUserWorkItem(new WaitCallback(threads[2].ThreadedProcessChannel), invertedb); WaitHandle.WaitAll(threadsDone); // Done with parallel section. rgbBitmap.rgb.r = invertedr.channel; rgbBitmap.rgb.g = invertedg.channel; rgbBitmap.rgb.b = invertedb.channel; ColorUtils.RGBBitmapToColorBitmap(ref rgbBitmap, ref colorBitmap); OnionLogger.globalLog.PopInfoLayer(); }