/// <summary>
        /// Flips (reflects the image) either vertical or horizontal.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="flipMode">The flip mode.</param>
        /// <returns>A new WriteableBitmap that is a flipped version of the input.</returns>
        public static BitmapBuffer Flip(this BitmapBuffer bmp, FlipMode flipMode)
        {
            using (BitmapContext context = bmp.GetBitmapContext(ReadWriteMode.ReadOnly))
            {
                // Use refs for faster access (really important!) speeds up a lot!
                int          w      = context.Width;
                int          h      = context.Height;
                int[]        p      = context.Pixels;
                int          i      = 0;
                BitmapBuffer result = BitmapBufferFactory.New(w, h);

                switch (flipMode)
                {
                default:
                    throw new NotSupportedException();

                case FlipMode.Vertical:
                    using (BitmapContext destContext = result.GetBitmapContext())
                    {
                        int[] rp = destContext.Pixels;
                        for (int y = h - 1; y >= 0; y--)
                        {
                            for (int x = 0; x < w; x++)
                            {
                                int srcInd = y * w + x;
                                rp[i] = p[srcInd];
                                i++;
                            }
                        }
                    }
                    break;

                case FlipMode.Horizontal:
                    using (BitmapContext destContext = result.GetBitmapContext())
                    {
                        int[] rp = destContext.Pixels;
                        for (int y = 0; y < h; y++)
                        {
                            for (int x = w - 1; x >= 0; x--)
                            {
                                int srcInd = y * w + x;
                                rp[i] = p[srcInd];
                                i++;
                            }
                        }
                    }
                    break;
                }
                return(result);
            }
        }
 /// <summary>
 /// Fills the whole WriteableBitmap with a color.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="color">The color used for filling.</param>
 public static void Clear(this BitmapBuffer bmp, ColorInt color)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         Clear(context, color);
     }
 }
Esempio n. 3
0
 /// <summary>
 /// Draws an anti-aliased, alpha blended, colored line by connecting two points using Wu's antialiasing algorithm
 /// Uses the pixels array and the width directly for best performance.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="x1">The x0.</param>
 /// <param name="y1">The y0.</param>
 /// <param name="x2">The x1.</param>
 /// <param name="y2">The y1.</param>
 /// <param name="sa">Alpha color component</param>
 /// <param name="sr">Premultiplied red color component</param>
 /// <param name="sg">Premultiplied green color component</param>
 /// <param name="sb">Premultiplied blue color component</param>
 /// <param name="clipRect">The region in the image to restrict drawing to.</param>
 public static void DrawLineWu(this BitmapBuffer bmp, int x1, int y1, int x2, int y2, int sa, int sr, int sg, int sb, RectD?clipRect = null)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         DrawLineWu(context, bmp.PixelWidth, bmp.PixelHeight, x1, y1, x2, y2, sa, sr, sg, sb, clipRect);
     }
 }
        ///// <summary>
        ///// Applies the given function to all the pixels of the bitmap in
        ///// order to set their color.
        ///// </summary>
        ///// <param name="bmp">The WriteableBitmap.</param>
        ///// <param name="func">The function to apply. With parameters x, y and a color as a result</param>
        //public static void dbugForEach(this BitmapBuffer bmp, Func<int, int, ColorInt> func)
        //{
        //    using (var context = bmp.GetBitmapContext())
        //    {
        //        int[] pixels = context.Pixels;
        //        int w = context.Width;
        //        int h = context.Height;
        //        int index = 0;

        //        for (int y = 0; y < h; y++)
        //        {
        //            for (int x = 0; x < w; x++)
        //            {
        //                pixels[index++] = func(x, y).ToPreMultAlphaColor();
        //            }
        //        }
        //    }
        //}

        ///// <summary>
        ///// Applies the given function to all the pixels of the bitmap in
        ///// order to set their color.
        ///// </summary>
        ///// <param name="bmp">The WriteableBitmap.</param>
        ///// <param name="func">The function to apply. With parameters x, y, source color and a color as a result</param>
        //public static void dbugForEach(this BitmapBuffer bmp, Func<int, int, ColorInt, ColorInt> func)
        //{
        //    using (var context = bmp.GetBitmapContext())
        //    {
        //        int[] pixels = context.Pixels;
        //        int w = context.Width;
        //        int h = context.Height;
        //        int index = 0;

        //        for (int y = 0; y < h; y++)
        //        {
        //            for (int x = 0; x < w; x++)
        //            {
        //                int c = pixels[index];

        //                // Premultiplied Alpha!
        //                byte a = (byte)(c >> 24);
        //                // Prevent division by zero
        //                int ai = a;
        //                if (ai == 0)
        //                {
        //                    ai = 1;
        //                }
        //                // Scale inverse alpha to use cheap integer mul bit shift
        //                ai = ((255 << 8) / ai);
        //                ColorInt srcColor = ColorInt.FromArgb(a,
        //                                              (byte)((((c >> 16) & 0xFF) * ai) >> 8),
        //                                              (byte)((((c >> 8) & 0xFF) * ai) >> 8),
        //                                              (byte)((((c & 0xFF) * ai) >> 8)));


        //                pixels[index++] = func(x, y, srcColor).ToPreMultAlphaColor();
        //            }
        //        }
        //    }
        //}


        /// <summary>
        /// Gets the color of the pixel at the x, y coordinate as integer.
        /// For best performance this method should not be used in iterative real-time scenarios. Implement the code directly inside a loop.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="x">The x coordinate of the pixel.</param>
        /// <param name="y">The y coordinate of the pixel.</param>
        /// <returns>The color of the pixel at x, y.</returns>
        public static int dbugGetPixeli(this BitmapBuffer bmp, int x, int y)
        {
            using (BitmapContext context = bmp.GetBitmapContext(ReadWriteMode.ReadOnly))
            {
                return(context.Pixels[y * context.Width + x]);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Creates a new WriteableBitmap which is the grayscaled version of this one and returns it. The gray values are equal to the brightness values.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <returns>The new gray WriteableBitmap.</returns>
        public static BitmapBuffer Gray(this BitmapBuffer bmp)
        {
            using (BitmapContext context = bmp.GetBitmapContext(ReadWriteMode.ReadOnly))
            {
                int          nWidth  = context.Width;
                int          nHeight = context.Height;
                int[]        px      = context.Pixels;
                BitmapBuffer result  = BitmapBufferFactory.New(nWidth, nHeight);

                using (BitmapContext dest = result.GetBitmapContext())
                {
                    int[] rp  = dest.Pixels;
                    int   len = context.Length;
                    for (int i = 0; i < len; i++)
                    {
                        // Extract
                        int c = px[i];
                        int a = (c >> 24) & 0xff;
                        int r = (c >> 16) & 0xff;
                        int g = (c >> 8) & 0xff;
                        int b = (c) & 0xff;

                        // Convert to gray with constant factors 0.2126, 0.7152, 0.0722
                        r = g = b = ((r * 6966 + g * 23436 + b * 2366) >> 15);

                        // Set
                        rp[i] = (a << 24) | (r << 16) | (g << 8) | b;
                    }
                }

                return(result);
            }
        }
 /// <summary>
 /// Sets the color of the pixel using an extra alpha value and a precalculated index (faster).
 /// For best performance this method should not be used in iterative real-time scenarios. Implement the code directly inside a loop.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="index">The coordinate index.</param>
 /// <param name="a">The alpha value of the color.</param>
 /// <param name="color">The color.</param>
 public static void SetPixeli(this BitmapBuffer bmp, int index, byte a, ColorInt color)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         context.Pixels[index] = color.ToPreMultAlphaColor();
     }
 }
Esempio n. 7
0
        /// <summary>
        /// Draws a closed Cardinal spline (cubic) defined by a point collection.
        /// The cardinal spline passes through each point in the collection.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="points">The points for the curve in x and y pairs, therefore the array is interpreted as (x1, y1, x2, y2, x3, y3, x4, y4, x1, x2 ..., xn, yn).</param>
        /// <param name="tension">The tension of the curve defines the shape. Usually between 0 and 1. 0 would be a straight line.</param>
        /// <param name="color">The color for the spline.</param>
        public static void DrawCurveClosed(this BitmapBuffer bmp, int[] points, float tension, int color)
        {
            using (BitmapContext context = bmp.GetBitmapContext())
            {
                // Use refs for faster access (really important!) speeds up a lot!
                int w = context.Width;
                int h = context.Height;

                int pn = points.Length;

                // First segment
                DrawCurveSegment(points[pn - 2], points[pn - 1], points[0], points[1], points[2], points[3], points[4], points[5], tension, color, context, w, h);

                // Middle segments
                int i;
                for (i = 2; i < pn - 4; i += 2)
                {
                    DrawCurveSegment(points[i - 2], points[i - 1], points[i], points[i + 1], points[i + 2], points[i + 3], points[i + 4], points[i + 5], tension, color, context, w, h);
                }

                // Last segment
                DrawCurveSegment(points[i - 2], points[i - 1], points[i], points[i + 1], points[i + 2], points[i + 3], points[0], points[1], tension, color, context, w, h);

                // Last-to-First segment
                DrawCurveSegment(points[i], points[i + 1], points[i + 2], points[i + 3], points[0], points[1], points[2], points[3], tension, color, context, w, h);
            }
        }
 /// <summary>
 /// Draws an anti-aliased line with a desired stroke thickness
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="x1">The x-coordinate of the start point.</param>
 /// <param name="y1">The y-coordinate of the start point.</param>
 /// <param name="x2">The x-coordinate of the end point.</param>
 /// <param name="y2">The y-coordinate of the end point.</param>
 /// <param name="color">The color for the line.</param>
 /// <param name="strokeThickness">The stroke thickness of the line.</param>
 /// </summary>
 public static void DrawLineAa(this BitmapBuffer bmp, int x1, int y1, int x2, int y2, ColorInt color, int strokeThickness, RectD?clipRect = null)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         AAWidthLine(bmp.PixelWidth, bmp.PixelHeight, context, x1, y1, x2, y2, strokeThickness, color.ToPreMultAlphaColor(), clipRect);
     }
 }
 /// <summary>
 /// Fills the whole WriteableBitmap with an empty color (0).
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 public static void Clear(this BitmapBuffer bmp)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         context.Clear();
     }
 }
Esempio n. 10
0
        /// <summary>
        /// Creates a new inverted WriteableBitmap and returns it.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <returns>The new inverted WriteableBitmap.</returns>
        public static BitmapBuffer Invert(this BitmapBuffer bmp)
        {
            using (BitmapContext srcContext = bmp.GetBitmapContext(ReadWriteMode.ReadOnly))
            {
                var result = BitmapBufferFactory.New(srcContext.Width, srcContext.Height);
                using (BitmapContext resultContext = result.GetBitmapContext())
                {
                    int[] rp     = resultContext.Pixels;
                    int[] p      = srcContext.Pixels;
                    int   length = srcContext.Length;

                    for (int i = 0; i < length; i++)
                    {
                        // Extract
                        int c = p[i];
                        int a = (c >> 24) & 0xff;
                        int r = (c >> 16) & 0xff;
                        int g = (c >> 8) & 0xff;
                        int b = (c) & 0xff;

                        // Invert
                        r = 255 - r;
                        g = 255 - g;
                        b = 255 - b;

                        // Set
                        rp[i] = (a << 24) | (r << 16) | (g << 8) | b;
                    }

                    return(result);
                }
            }
        }
 /// <summary>
 /// Sets the color of the pixel.
 /// For best performance this method should not be used in iterative real-time scenarios. Implement the code directly inside a loop.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="x">The x coordinate (row).</param>
 /// <param name="y">The y coordinate (column).</param>
 /// <param name="color">The color.</param>
 public static void SetPixel(this BitmapBuffer bmp, int x, int y, int color)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         context.Pixels[y * context.Width + x] = color;
     }
 }
Esempio n. 12
0
 /// <summary>
 /// Draws a colored line by connecting two points using an optimized DDA.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="x1">The x-coordinate of the start point.</param>
 /// <param name="y1">The y-coordinate of the start point.</param>
 /// <param name="x2">The x-coordinate of the end point.</param>
 /// <param name="y2">The y-coordinate of the end point.</param>
 /// <param name="color">The color for the line.</param>
 /// <param name="clipRect">The region in the image to restrict drawing to.</param>
 public static void DrawLine(this BitmapBuffer bmp, int x1, int y1, int x2, int y2, int color, RectD?clipRect = null)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         DrawLine(context, context.Width, context.Height, x1, y1, x2, y2, color, clipRect);
     }
 }
 /// <summary>
 /// Sets the color of the pixel.
 /// For best performance this method should not be used in iterative real-time scenarios. Implement the code directly inside a loop.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="x">The x coordinate (row).</param>
 /// <param name="y">The y coordinate (column).</param>
 /// <param name="color">The color.</param>
 public static void SetPixel(this BitmapBuffer bmp, int x, int y, ColorInt color)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         context.Pixels[y * context.Width + x] = color.ToPreMultAlphaColor();
     }
 }
 /// <summary>
 /// Sets the color of the pixel using a precalculated index (faster).
 /// For best performance this method should not be used in iterative real-time scenarios. Implement the code directly inside a loop.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="index">The coordinate index.</param>
 /// <param name="color">The color.</param>
 public static void SetPixeli(this BitmapBuffer bmp, int index, int color)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         context.Pixels[index] = color;
     }
 }
 /// <summary>
 /// Sets the color of the pixel including the alpha value.
 /// For best performance this method should not be used in iterative real-time scenarios. Implement the code directly inside a loop.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="x">The x coordinate (row).</param>
 /// <param name="y">The y coordinate (column).</param>
 /// <param name="a">The alpha value of the color.</param>
 /// <param name="r">The red value of the color.</param>
 /// <param name="g">The green value of the color.</param>
 /// <param name="b">The blue value of the color.</param>
 public static void SetPixel(this BitmapBuffer bmp, int x, int y, byte a, byte r, byte g, byte b)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         context.Pixels[y * context.Width + x] = (a << 24) | (r << 16) | (g << 8) | b;
     }
 }
 /// <summary>
 /// Sets the color of the pixel including the alpha value and using a precalculated index (faster).
 /// For best performance this method should not be used in iterative real-time scenarios. Implement the code directly inside a loop.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="index">The coordinate index.</param>
 /// <param name="a">The alpha value of the color.</param>
 /// <param name="r">The red value of the color.</param>
 /// <param name="g">The green value of the color.</param>
 /// <param name="b">The blue value of the color.</param>
 public static void SetPixeli(this BitmapBuffer bmp, int index, byte a, byte r, byte g, byte b)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         context.Pixels[index] = (a << 24) | (r << 16) | (g << 8) | b;
     }
 }
 /// <summary>
 /// Sets the color of the pixel using an extra alpha value.
 /// For best performance this method should not be used in iterative real-time scenarios. Implement the code directly inside a loop.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="x">The x coordinate (row).</param>
 /// <param name="y">The y coordinate (column).</param>
 /// <param name="a">The alpha value of the color.</param>
 /// <param name="color">The color.</param>
 public static void SetPixel(this BitmapBuffer bmp, int x, int y, byte a, ColorInt color)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         // Add one to use mul and cheap bit shift for multiplicaltion
         context.Pixels[y * context.Width + x] = color.ToPreMultAlphaColor();
     }
 }
Esempio n. 18
0
 /// <summary>
 /// Copies color information from an ARGB byte array into this WriteableBitmap starting at a specific buffer index.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="offset">The starting index in the buffer.</param>
 /// <param name="count">The number of bytes to copy from the buffer.</param>
 /// <param name="buffer">The color buffer as byte ARGB values.</param>
 /// <returns>The WriteableBitmap that was passed as parameter.</returns>
 public static BitmapBuffer FromByteArray(this BitmapBuffer bmp, byte[] buffer, int offset, int count)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         BitmapContext.BlockCopy(buffer, offset, context, 0, count);
         return(bmp);
     }
 }
Esempio n. 19
0
        private const byte TOP    = 8; // 1000

        /// <summary>
        /// Draws a line using a pen / stamp for the line
        /// </summary>
        /// <param name="bmp">The WriteableBitmap containing the pixels as int RGBA value.</param>
        /// <param name="w">The width of one scanline in the pixels array.</param>
        /// <param name="h">The height of the bitmap.</param>
        /// <param name="x1">The x-coordinate of the start point.</param>
        /// <param name="y1">The y-coordinate of the start point.</param>
        /// <param name="x2">The x-coordinate of the end point.</param>
        /// <param name="y2">The y-coordinate of the end point.</param>
        /// <param name="penBmp">The pen bitmap.</param>
        public static void DrawLinePenned(this BitmapBuffer bmp, int x1, int y1, int x2, int y2, BitmapBuffer penBmp, RectD?clipRect = null)
        {
            using (BitmapContext context = bmp.GetBitmapContext())
                using (BitmapContext penContext = penBmp.GetBitmapContext(ReadWriteMode.ReadOnly))
                {
                    DrawLinePenned(context, bmp.PixelWidth, bmp.PixelHeight, x1, y1, x2, y2, penContext, clipRect);
                }
        }
Esempio n. 20
0
        /// <summary>
        /// Draws a colored line by connecting two points using a DDA algorithm (Digital Differential Analyzer).
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="x1">The x-coordinate of the start point.</param>
        /// <param name="y1">The y-coordinate of the start point.</param>
        /// <param name="x2">The x-coordinate of the end point.</param>
        /// <param name="y2">The y-coordinate of the end point.</param>
        /// <param name="color">The color for the line.</param>
        /// <param name="clipRect">The region in the image to restrict drawing to.</param>
        public static unsafe void DrawLineDDA(this BitmapBuffer bmp, int x1, int y1, int x2, int y2, int color, RectD?clipRect = null)
        {
            using (BitmapContext context = bmp.GetBitmapContext())
            {
                // Use refs for faster access (really important!) speeds up a lot!
                int  w      = context.Width;
                int  h      = context.Height;
                int *pixels = context.Pixels._inf32Buffer;

                // Get clip coordinates
                int clipX1 = 0;
                int clipX2 = w;
                int clipY1 = 0;
                int clipY2 = h;
                if (clipRect.HasValue)
                {
                    RectD c = clipRect.Value;
                    clipX1 = (int)c.X;
                    clipX2 = (int)(c.X + c.Width);
                    clipY1 = (int)c.Y;
                    clipY2 = (int)(c.Y + c.Height);
                }

                // Distance start and end point
                int dx = x2 - x1;
                int dy = y2 - y1;

                // Determine slope (absolute value)
                int len  = dy >= 0 ? dy : -dy;
                int lenx = dx >= 0 ? dx : -dx;
                if (lenx > len)
                {
                    len = lenx;
                }

                // Prevent division by zero
                if (len != 0)
                {
                    // Init steps and start
                    float incx = dx / (float)len;
                    float incy = dy / (float)len;
                    float x    = x1;
                    float y    = y1;

                    // Walk the line!
                    for (int i = 0; i < len; i++)
                    {
                        if (y < clipY2 && y >= clipY1 && x < clipX2 && x >= clipX1)
                        {
                            pixels[(int)y * w + (int)x] = color;
                        }
                        x += incx;
                        y += incy;
                    }
                }
            }
        }
Esempio n. 21
0
 /// <summary>
 /// Sets the color of the pixel using a precalculated index (faster).
 /// For best performance this method should not be used in iterative real-time scenarios. Implement the code directly inside a loop.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <param name="index">The coordinate index.</param>
 /// <param name="r">The red value of the color.</param>
 /// <param name="g">The green value of the color.</param>
 /// <param name="b">The blue value of the color.</param>
 public static void SetPixeli(this BitmapBuffer bmp, int index, byte r, byte g, byte b)
 {
     using (BitmapContext context = bmp.GetBitmapContext())
     {
         unsafe
         {
             context.Pixels._inf32Buffer[index] = (255 << 24) | (r << 16) | (g << 8) | b;
         }
     }
 }
 /// <summary>
 /// Clones the specified WriteableBitmap.
 /// </summary>
 /// <param name="bmp">The WriteableBitmap.</param>
 /// <returns>A copy of the WriteableBitmap.</returns>
 public static BitmapBuffer Clone(this BitmapBuffer bmp)
 {
     using (BitmapContext srcContext = bmp.GetBitmapContext(ReadWriteMode.ReadOnly))
     {
         BitmapBuffer result = BitmapBufferFactory.New(srcContext.Width, srcContext.Height);
         using (var destContext = result.GetBitmapContext())
         {
             BitmapContext.BlockCopy(srcContext, 0, destContext, 0, srcContext.Length * ARGB_SIZE);
         }
         return(result);
     }
 }
Esempio n. 23
0
        /// <summary>
        /// Draws a cubic Beziér spline defined by start, end and two control points.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="x1">The x-coordinate of the start point.</param>
        /// <param name="y1">The y-coordinate of the start point.</param>
        /// <param name="cx1">The x-coordinate of the 1st control point.</param>
        /// <param name="cy1">The y-coordinate of the 1st control point.</param>
        /// <param name="cx2">The x-coordinate of the 2nd control point.</param>
        /// <param name="cy2">The y-coordinate of the 2nd control point.</param>
        /// <param name="x2">The x-coordinate of the end point.</param>
        /// <param name="y2">The y-coordinate of the end point.</param>
        /// <param name="color">The color.</param>
        public static void DrawBezier(this BitmapBuffer bmp, int x1, int y1, int cx1, int cy1, int cx2, int cy2, int x2, int y2, int color)
        {
            // Determine distances between controls points (bounding rect) to find the optimal stepsize
            int minX = Math.Min(x1, Math.Min(cx1, Math.Min(cx2, x2)));
            int minY = Math.Min(y1, Math.Min(cy1, Math.Min(cy2, y2)));
            int maxX = Math.Max(x1, Math.Max(cx1, Math.Max(cx2, x2)));
            int maxY = Math.Max(y1, Math.Max(cy1, Math.Max(cy2, y2)));

            // Get slope
            int lenx = maxX - minX;
            int len  = maxY - minY;

            if (lenx > len)
            {
                len = lenx;
            }

            // Prevent division by zero
            if (len != 0)
            {
                using (BitmapContext context = bmp.GetBitmapContext())
                {
                    // Use refs for faster access (really important!) speeds up a lot!
                    int w = context.Width;
                    int h = context.Height;

                    // Init vars
                    float step = STEP_FACTOR / len;
                    int   tx1 = x1;
                    int   ty1 = y1;
                    int   tx2, ty2;

                    // Interpolate
                    for (float t = step; t <= 1; t += step)
                    {
                        float tSq  = t * t;
                        float t1   = 1 - t;
                        float t1Sq = t1 * t1;

                        tx2 = (int)(t1 * t1Sq * x1 + 3 * t * t1Sq * cx1 + 3 * t1 * tSq * cx2 + t * tSq * x2);
                        ty2 = (int)(t1 * t1Sq * y1 + 3 * t * t1Sq * cy1 + 3 * t1 * tSq * cy2 + t * tSq * y2);

                        // Draw line
                        DrawLine(context, w, h, tx1, ty1, tx2, ty2, color);
                        tx1 = tx2;
                        ty1 = ty2;
                    }

                    // Prevent rounding gap
                    DrawLine(context, w, h, tx1, ty1, x2, y2, color);
                }
            }
        }
        /// <summary>
        /// Creates a new resized WriteableBitmap.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="width">The new desired width.</param>
        /// <param name="height">The new desired height.</param>
        /// <param name="interpolation">The interpolation method that should be used.</param>
        /// <returns>A new WriteableBitmap that is a resized version of the input.</returns>
        public static BitmapBuffer Resize(this BitmapBuffer bmp, int width, int height, Interpolation interpolation)
        {
            using (BitmapContext srcContext = bmp.GetBitmapContext(ReadWriteMode.ReadOnly))
            {
                int[] pd = Resize(srcContext, srcContext.Width, srcContext.Height, width, height, interpolation);

                BitmapBuffer result = BitmapBufferFactory.New(width, height);
                using (BitmapContext dstContext = result.GetBitmapContext())
                {
                    BitmapContext.BlockCopy(pd, 0, dstContext, 0, ARGB_SIZE * pd.Length);
                }
                return(result);
            }
        }
        /// <summary>
        /// Gets the brightness / luminance of the pixel at the x, y coordinate as byte.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="x">The x coordinate of the pixel.</param>
        /// <param name="y">The y coordinate of the pixel.</param>
        /// <returns>The brightness of the pixel at x, y.</returns>
        public static byte GetBrightness(this BitmapBuffer bmp, int x, int y)
        {
            using (BitmapContext context = bmp.GetBitmapContext(ReadWriteMode.ReadOnly))
            {
                // Extract color components
                int  c = context.Pixels[y * context.Width + x];
                byte r = (byte)(c >> 16);
                byte g = (byte)(c >> 8);
                byte b = (byte)(c);

                // Convert to gray with constant factors 0.2126, 0.7152, 0.0722
                return((byte)((r * 6966 + g * 23436 + b * 2366) >> 15));
            }
        }
Esempio n. 26
0
        /// <summary>
        /// Creates a new WriteableBitmap which is contrast adjusted version of this one and returns it.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="level">Level of contrast as double. [-255.0, 255.0] </param>
        /// <returns>The new WriteableBitmap.</returns>
        public static BitmapBuffer AdjustContrast(this BitmapBuffer bmp, double level)
        {
            int factor = (int)((259.0 * (level + 255.0)) / (255.0 * (259.0 - level)) * 255.0);

            using (BitmapContext context = bmp.GetBitmapContext(ReadWriteMode.ReadOnly))
            {
                int nWidth  = context.Width;
                int nHeight = context.Height;

                unsafe
                {
                    NativeInt32Arr px1    = context.Pixels;
                    int *          px     = px1._inf32Buffer;
                    BitmapBuffer   result = BitmapBufferFactory.New(nWidth, nHeight);

                    using (BitmapContext dest = result.GetBitmapContext())
                    {
                        NativeInt32Arr rp1 = dest.Pixels;
                        int *          rp  = rp1._inf32Buffer;
                        int            len = context.Length;
                        for (int i = 0; i < len; i++)
                        {
                            // Extract
                            int c = px[i];
                            int a = (c >> 24) & 0xff;
                            int r = (c >> 16) & 0xff;
                            int g = (c >> 8) & 0xff;
                            int b = (c) & 0xff;

                            // Adjust contrast based on computed factor
                            //TODO: create lookup table for this
                            r = ((factor * (r - 128)) >> 8) + 128;
                            g = ((factor * (g - 128)) >> 8) + 128;
                            b = ((factor * (b - 128)) >> 8) + 128;

                            // Clamp
                            r = r < 0 ? 0 : r > 255 ? 255 : r;
                            g = g < 0 ? 0 : g > 255 ? 255 : g;
                            b = b < 0 ? 0 : b > 255 ? 255 : b;

                            // Set
                            rp[i] = (a << 24) | (r << 16) | (g << 8) | b;
                        }
                    }
                    return(result);
                }
            }
        }
Esempio n. 27
0
        /// <summary>
        /// Copies the Pixels from the WriteableBitmap into a ARGB byte array starting at a specific Pixels index.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="offset">The starting Pixels index.</param>
        /// <param name="count">The number of Pixels to copy, -1 for all</param>
        /// <returns>The color buffer as byte ARGB values.</returns>
        public static byte[] ToByteArray(this BitmapBuffer bmp, int offset, int count)
        {
            using (BitmapContext context = bmp.GetBitmapContext(ReadWriteMode.ReadOnly))
            {
                if (count == -1)
                {
                    // Copy all to byte array
                    count = context.Length;
                }

                int    len    = count * ARGB_SIZE;
                byte[] result = new byte[len]; // ARGB
                BitmapContext.BlockCopy(context, offset, result, 0, len);
                return(result);
            }
        }
        /// <summary>
        /// Creates a new cropped WriteableBitmap.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="x">The x coordinate of the rectangle that defines the crop region.</param>
        /// <param name="y">The y coordinate of the rectangle that defines the crop region.</param>
        /// <param name="width">The width of the rectangle that defines the crop region.</param>
        /// <param name="height">The height of the rectangle that defines the crop region.</param>
        /// <returns>A new WriteableBitmap that is a cropped version of the input.</returns>
        public static BitmapBuffer Crop(this BitmapBuffer bmp, int x, int y, int width, int height)
        {
            using (BitmapContext srcContext = bmp.GetBitmapContext(ReadWriteMode.ReadOnly))
            {
                int srcWidth  = srcContext.Width;
                int srcHeight = srcContext.Height;

                // If the rectangle is completely out of the bitmap
                if (x > srcWidth || y > srcHeight)
                {
                    return(BitmapBufferFactory.New(0, 0));
                }

                // Clamp to boundaries
                if (x < 0)
                {
                    x = 0;
                }
                if (x + width > srcWidth)
                {
                    width = srcWidth - x;
                }
                if (y < 0)
                {
                    y = 0;
                }
                if (y + height > srcHeight)
                {
                    height = srcHeight - y;
                }

                // Copy the pixels line by line using fast BlockCopy
                BitmapBuffer result = BitmapBufferFactory.New(width, height);
                using (BitmapContext destContext = result.GetBitmapContext())
                {
                    for (int line = 0; line < height; line++)
                    {
                        int srcOff = ((y + line) * srcWidth + x) * ARGB_SIZE;
                        int dstOff = line * width * ARGB_SIZE;
                        BitmapContext.BlockCopy(srcContext, srcOff, destContext, dstOff, width * ARGB_SIZE);
                    }
                    return(result);
                }
            }
        }
Esempio n. 29
0
        /// <summary>
        /// Creates a new WriteableBitmap which is gamma adjusted version of this one and returns it.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="value">Value of gamma for adjustment. Original is 1.0.</param>
        /// <returns>The new WriteableBitmap.</returns>
        public static unsafe BitmapBuffer AdjustGamma(this BitmapBuffer bmp, double value)
        {
            using (BitmapContext context = bmp.GetBitmapContext(ReadWriteMode.ReadOnly))
            {
                int          nWidth    = context.Width;
                int          nHeight   = context.Height;
                int *        srcPixels = context.Pixels._inf32Buffer;
                BitmapBuffer result    = BitmapBufferFactory.New(nWidth, nHeight);

                using (BitmapContext dest = result.GetBitmapContext())
                {
                    int *rp = dest.Pixels._inf32Buffer;
                    var  gammaCorrection = 1.0 / value;
                    int  len             = context.Length;
                    for (int i = 0; i < len; i++)
                    {
                        // Extract
                        int c = srcPixels[i];
                        int a = (c >> 24) & 0xff;
                        int r = (c >> 16) & 0xff;
                        int g = (c >> 8) & 0xff;
                        int b = (c) & 0xff;

                        //Gamma adjustment
                        //TODO: create gamma-lookup table for this ***
                        r = (int)(255.0 * Math.Pow((r / 255.0), gammaCorrection));
                        g = (int)(255.0 * Math.Pow((g / 255.0), gammaCorrection));
                        b = (int)(255.0 * Math.Pow((b / 255.0), gammaCorrection));

                        // Clamps
                        r = r < 0 ? 0 : r > 255 ? 255 : r;
                        g = g < 0 ? 0 : g > 255 ? 255 : g;
                        b = b < 0 ? 0 : b > 255 ? 255 : b;

                        // Set
                        rp[i] = (a << 24) | (r << 16) | (g << 8) | b;
                    }
                }

                return(result);
            }
        }
Esempio n. 30
0
        /// <summary>
        /// Creates a new WriteableBitmap which is brightness adjusted version of this one and returns it.
        /// </summary>
        /// <param name="bmp">The WriteableBitmap.</param>
        /// <param name="nLevel">Level of contrast as double. [-255.0, 255.0] </param>
        /// <returns>The new WriteableBitmap.</returns>
        public static unsafe BitmapBuffer AdjustBrightness(this BitmapBuffer bmp, int nLevel)
        {
            using (BitmapContext context = bmp.GetBitmapContext(ReadWriteMode.ReadOnly))
            {
                int          nWidth  = context.Width;
                int          nHeight = context.Height;
                int *        px      = context.Pixels._inf32Buffer;
                BitmapBuffer result  = BitmapBufferFactory.New(nWidth, nHeight);

                using (BitmapContext dest = result.GetBitmapContext())
                {
                    int *rp  = dest.Pixels._inf32Buffer;
                    int  len = context.Length;
                    for (int i = 0; i < len; i++)
                    {
                        // Extract
                        int c = px[i];
                        int a = (c >> 24) & 0xff;
                        int r = (c >> 16) & 0xff;
                        int g = (c >> 8) & 0xff;
                        int b = (c) & 0xff;

                        // Brightness adjustment
                        //TODO: create lookup table for this
                        r += nLevel;
                        g += nLevel;
                        b += nLevel;

                        // Clamp
                        r = r < 0 ? 0 : r > 255 ? 255 : r;
                        g = g < 0 ? 0 : g > 255 ? 255 : g;
                        b = b < 0 ? 0 : b > 255 ? 255 : b;

                        // Set
                        rp[i] = (a << 24) | (r << 16) | (g << 8) | b;
                    }
                }

                return(result);
            }
        }