/// <summary>
        /// given a location of a pixel (x,y), returns the info about that pixel.
        /// </summary>
        /// <param name="i"></param>
        /// <param name="j"></param>
        /// <param name="imageDataArray"></param>
        /// <param name="injectedContext"></param>
        /// <returns></returns>
        public pixel getPixelInfo(int i, int j, byte[] imageDataArray, SeamCarvingContext injectedContext)
        {
            byte[] red = { 0, 0, 0, this.getPixel(imageDataArray, i, j, 0, injectedContext) };
            byte[] green = { 0, 0, 0, this.getPixel(imageDataArray, i, j, 1, injectedContext) };
            byte[] blue = { 0, 0, 0, this.getPixel(imageDataArray, i, j, 2, injectedContext) };
            byte[] alpha = { 0, 0, 0, this.getPixel(imageDataArray, i, j, 3, injectedContext) };

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(red);
                Array.Reverse(green);
                Array.Reverse(blue);
                Array.Reverse(alpha);
            }

            int redInt = BitConverter.ToInt32(red, 0);
            int greenInt = BitConverter.ToInt32(green, 0);
            int blueInt = BitConverter.ToInt32(blue, 0);
            int alphaInt = BitConverter.ToInt32(alpha, 0);

            pixel toReturn = new pixel();
            toReturn.red = redInt;
            toReturn.green = greenInt;
            toReturn.blue = blueInt;
            toReturn.alpha = alphaInt;

            return toReturn;
        }
 /// <summary>
 /// takes a given bitmapImage and copies it into a new byte array and returns it.
 /// </summary>
 /// <param name="img"></param>
 /// <param name="injectedContext"></param>
 /// <returns></returns>
 public byte[] ImageToByte(BitmapImage toCopy, SeamCarvingContext injectedContext)
 {
     injectedContext.stride = toCopy.PixelWidth * 4;
     int size = toCopy.PixelHeight * injectedContext.stride;
     byte[] pixels = new byte[size];
     toCopy.CopyPixels(pixels, injectedContext.stride, 0);
     return pixels;
 }
 /// <summary>
 /// find the minimum index in the right most column of a two dimensional array represented as a one dimensional array
 /// </summary>
 /// <param name="arr"></param>
 /// <param name="injectedContext"></param>
 /// <returns></returns>
 public int findMinIndex(int[] arr, SeamCarvingContext injectedContext)
 {
     int lowest = Int32.MaxValue;
     int toReturn = 0;
     for (int i = 0; i < injectedContext.Height; i++)
     {
         int current = this.getIndex(arr, i, (int)injectedContext.Width - 2, injectedContext);
         if (current < lowest)
         {
             lowest = current;
             toReturn = i;
         }
     }
     return toReturn;
 }
Esempio n. 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="injectedContext"></param>
        public void calculateSeam(SeamCarvingContext injectedContext)
        {
            injectedContext.dirtyArray = new int[injectedContext.energy.Length];

            int j = this.seamUtilities.findMinIndex(injectedContext.energy, injectedContext);

            for (int i = (int)injectedContext.Width - 2; i >= 0; i--)
            {
                if (j == 0)
                {
                    j += 1;
                }
                int up   = this.seamUtilities.getIndex(injectedContext.energy, j + 1, i, injectedContext);
                int lat  = this.seamUtilities.getIndex(injectedContext.energy, j, i, injectedContext);
                int down = this.seamUtilities.getIndex(injectedContext.energy, j - 1, i, injectedContext);

                if (up < lat && up < down)
                {
                    seamUtilities.setPixel(injectedContext.imageDataArray, j, i, 2, 0xff, injectedContext);
                    seamUtilities.setPixel(injectedContext.imageDataArray, j, i, 1, 0x00, injectedContext);
                    seamUtilities.setPixel(injectedContext.imageDataArray, j, i, 0, 0x00, injectedContext);
                    seamUtilities.setPixel(injectedContext.imageDataArray, j, i, 3, 0xff, injectedContext);
                    this.seamUtilities.setIndex(injectedContext.dirtyArray, j, i, 1, injectedContext);
                    j = j + 1;
                }
                else if (lat < down && lat < up)
                {
                    seamUtilities.setPixel(injectedContext.imageDataArray, j, i, 2, 0xff, injectedContext);
                    seamUtilities.setPixel(injectedContext.imageDataArray, j, i, 1, 0x00, injectedContext);
                    seamUtilities.setPixel(injectedContext.imageDataArray, j, i, 3, 0xff, injectedContext);
                    seamUtilities.setPixel(injectedContext.imageDataArray, j, i, 0, 0x00, injectedContext);
                    this.seamUtilities.setIndex(injectedContext.dirtyArray, j, i, 1, injectedContext);
                }
                else
                {
                    seamUtilities.setPixel(injectedContext.imageDataArray, j, i, 2, 0xff, injectedContext);
                    seamUtilities.setPixel(injectedContext.imageDataArray, j, i, 3, 0xff, injectedContext);
                    seamUtilities.setPixel(injectedContext.imageDataArray, j, i, 1, 0x00, injectedContext);
                    seamUtilities.setPixel(injectedContext.imageDataArray, j, i, 0, 0x00, injectedContext);
                    this.seamUtilities.setIndex(injectedContext.dirtyArray, j, i, 1, injectedContext);
                    j = j - 1;
                }
            }
        }
        /// <summary>
        /// given a seam carving context, calculates the gradient of every pixel.
        /// </summary>
        /// <param name="injectedContext"></param>
        public void calculateGradient(SeamCarvingContext injectedContext)
        {
            injectedContext.gradientArray = new byte[injectedContext.imageDataArray.Length];
            for (int i = 1; i < injectedContext.Height - 1; i++)
            {
                for (int j = 1; j < injectedContext.Width - 1; j++)
                {
                    pixel last    = seamUtilities.getPixelInfo(i, j - 1, injectedContext.imageDataArray, injectedContext);
                    pixel current = seamUtilities.getPixelInfo(i, j, injectedContext.imageDataArray, injectedContext);
                    pixel next    = seamUtilities.getPixelInfo(i, j + 1, injectedContext.imageDataArray, injectedContext);

                    byte gradient = calculateGradientOfPixel(last, current, next);

                    seamUtilities.setPixel(injectedContext.gradientArray, i, j, 0, gradient, injectedContext);
                    seamUtilities.setPixel(injectedContext.gradientArray, i, j, 1, gradient, injectedContext);
                    seamUtilities.setPixel(injectedContext.gradientArray, i, j, 2, gradient, injectedContext);
                    seamUtilities.setPixel(injectedContext.gradientArray, i, j, 3, 0xff, injectedContext);
                }
            }
        }
        /// <summary>
        /// calculates the heatmap of the given seam carving context
        /// </summary>
        /// <param name="injectedContext"></param>
        public void calculateHeat(SeamCarvingContext injectedContext)
        {
            injectedContext.energyArray = injectedContext.gradientArray;
            injectedContext.energy      = new int[injectedContext.gradientArray.Length / 4];
            for (int i = 0; i < injectedContext.Height; i++)
            {
                byte current = this.seamUtilities.getPixel(injectedContext.gradientArray, i, 0, 0, injectedContext);
                this.seamUtilities.setIndex(injectedContext.energy, i, 0, (int)current, injectedContext);
            }

            for (int i = 1; i < injectedContext.Width - 1; i++)
            {
                for (int j = 0; j < injectedContext.Height; j++)
                {
                    if (j == 0 || j == (injectedContext.Height - 1))
                    {
                        this.seamUtilities.setIndex(injectedContext.energy, j, i, Int32.MaxValue, injectedContext);
                    }
                    else
                    {
                        int current = (int)this.seamUtilities.getPixel(injectedContext.gradientArray, j, i, 0, injectedContext);
                        int neg     = this.seamUtilities.getIndex(injectedContext.energy, j - 1, i - 1, injectedContext);
                        int lat     = this.seamUtilities.getIndex(injectedContext.energy, j, i - 1, injectedContext);
                        int pos     = this.seamUtilities.getIndex(injectedContext.energy, j + 1, i - 1, injectedContext);
                        int least   = (Math.Min(Math.Min(neg, lat), pos));
                        int toSet   = current + least;
                        int maxVal  = 255 * (int)injectedContext.Width;
                        this.seamUtilities.setIndex(injectedContext.energy, j, i, (current + least), injectedContext);

                        double ratio = (((double)toSet) / ((double)maxVal)) * 128;

                        byte pixelValue = (byte)(ratio * 256);

                        this.seamUtilities.setPixel(injectedContext.energyArray, j, i, 0, pixelValue, injectedContext);
                        this.seamUtilities.setPixel(injectedContext.energyArray, j, i, 1, pixelValue, injectedContext);
                        this.seamUtilities.setPixel(injectedContext.energyArray, j, i, 2, pixelValue, injectedContext);
                    }
                }
            }
        }
 /// <summary>
 /// gets the pixel value from a given byte array at location (x,y) with the given color.
 /// </summary>
 /// <param name="arr"></param>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="color"></param>
 /// <returns></returns>
 public byte getPixel(byte[] arr, int x, int y, int color, SeamCarvingContext context)
 {
     int index = (int)context.Width * 4 * x + y * 4;
     return arr[index + color];
 }
 /// <summary>
 /// sets the pixel value in the given byte array at location (x,y) with the given color to the given value.
 /// </summary>
 /// <param name="arr"></param>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="color"></param>
 /// <param name="toSet"></param>
 public void setPixel(byte[] arr, int x, int y, int color, byte toSet, SeamCarvingContext context)
 {
     int index = (int)context.Width * 4 * x + y * 4;
     arr[index + color] = toSet;
 }
 /// <summary>
 /// get index form the given array.
 /// </summary>
 /// <param name="arr"></param>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="injectedContext"></param>
 /// <returns></returns>
 public int getIndex(int[] arr, int x, int y, SeamCarvingContext injectedContext)
 {
     int index = x * (int)injectedContext.Width + y;
     return arr[index];
 }
 /// <summary>
 /// set index of pixel in array
 /// </summary>
 /// <param name="arr"></param>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="toSet"></param>
 /// <param name="injectedContext"></param>
 public void setIndex(int[] arr, int x, int y, int toSet, SeamCarvingContext injectedContext)
 {
     int index = x * (int)injectedContext.Width + y;
     arr[index] = toSet;
 }