Esempio n. 1
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. 2
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;

                unsafe
                {
                    BitmapBuffer result = BitmapBufferFactory.New(nWidth, nHeight);
                    using (BitmapContext dest = result.GetBitmapContext())
                    {
                        NativeInt32Arr px1 = context.Pixels;
                        NativeInt32Arr rp1 = dest.Pixels;
                        int            len = context.Length;
                        int *          px  = px1._inf32Buffer;
                        int *          rp  = rp1._inf32Buffer;

                        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);
                }
            }
        }
        private static void AAWidthLine(int width, int height, BitmapContext context, float x1, float y1, float x2, float y2, float lineWidth, Int32 color, RectD?clipRect = null)
        {
            // Perform cohen-sutherland clipping if either point is out of the viewport
            if (!CohenSutherlandLineClip(clipRect ?? new RectD(0, 0, width, height), ref x1, ref y1, ref x2, ref y2))
            {
                return;
            }

            if (lineWidth <= 0)
            {
                return;
            }

            unsafe
            {
                NativeInt32Arr buffer1 = context.Pixels;
                int *          buffer  = buffer1._inf32Buffer;

                if (y1 > y2)
                {
                    Swap(ref x1, ref x2);
                    Swap(ref y1, ref y2);
                }

                if (x1 == x2)
                {
                    x1 -= (int)lineWidth / 2;
                    x2 += (int)lineWidth / 2;

                    if (x1 < 0)
                    {
                        x1 = 0;
                    }
                    if (x2 < 0)
                    {
                        return;
                    }

                    if (x1 >= width)
                    {
                        return;
                    }
                    if (x2 >= width)
                    {
                        x2 = width - 1;
                    }

                    if (y1 >= height || y2 < 0)
                    {
                        return;
                    }

                    if (y1 < 0)
                    {
                        y1 = 0;
                    }
                    if (y2 >= height)
                    {
                        y2 = height - 1;
                    }

                    for (int x = (int)x1; x <= x2; x++)
                    {
                        for (int y = (int)y1; y <= y2; y++)
                        {
                            byte a = (byte)((color & 0xff000000) >> 24);
                            byte r = (byte)((color & 0x00ff0000) >> 16);
                            byte g = (byte)((color & 0x0000ff00) >> 8);
                            byte b = (byte)((color & 0x000000ff) >> 0);

                            byte rs, gs, bs;
                            byte rd, gd, bd;

                            int d;

                            rs = r;
                            gs = g;
                            bs = b;

                            d = buffer[y * width + x];

                            rd = (byte)((d & 0x00ff0000) >> 16);
                            gd = (byte)((d & 0x0000ff00) >> 8);
                            bd = (byte)((d & 0x000000ff) >> 0);

                            rd = (byte)((rs * a + rd * (0xff - a)) >> 8);
                            gd = (byte)((gs * a + gd * (0xff - a)) >> 8);
                            bd = (byte)((bs * a + bd * (0xff - a)) >> 8);

                            buffer[y * width + x] = (0xff << 24) | (rd << 16) | (gd << 8) | (bd << 0);
                        }
                    }

                    return;
                }
                if (y1 == y2)
                {
                    if (x1 > x2)
                    {
                        Swap(ref x1, ref x2);
                    }

                    y1 -= (int)lineWidth / 2;
                    y2 += (int)lineWidth / 2;

                    if (y1 < 0)
                    {
                        y1 = 0;
                    }
                    if (y2 < 0)
                    {
                        return;
                    }

                    if (y1 >= height)
                    {
                        return;
                    }
                    if (y2 >= height)
                    {
                        y2 = height - 1;
                    }

                    if (x1 >= width || y2 < 0)
                    {
                        return;
                    }

                    if (x1 < 0)
                    {
                        x1 = 0;
                    }
                    if (x2 >= width)
                    {
                        x2 = width - 1;
                    }

                    for (int x = (int)x1; x <= x2; x++)
                    {
                        for (int y = (int)y1; y <= y2; y++)
                        {
                            byte a = (byte)((color & 0xff000000) >> 24);
                            byte r = (byte)((color & 0x00ff0000) >> 16);
                            byte g = (byte)((color & 0x0000ff00) >> 8);
                            byte b = (byte)((color & 0x000000ff) >> 0);

                            Byte rs, gs, bs;
                            Byte rd, gd, bd;

                            Int32 d;

                            rs = r;
                            gs = g;
                            bs = b;

                            d = buffer[y * width + x];

                            rd = (byte)((d & 0x00ff0000) >> 16);
                            gd = (byte)((d & 0x0000ff00) >> 8);
                            bd = (byte)((d & 0x000000ff) >> 0);

                            rd = (byte)((rs * a + rd * (0xff - a)) >> 8);
                            gd = (byte)((gs * a + gd * (0xff - a)) >> 8);
                            bd = (byte)((bs * a + bd * (0xff - a)) >> 8);

                            buffer[y * width + x] = (0xff << 24) | (rd << 16) | (gd << 8) | (bd << 0);
                        }
                    }

                    return;
                }

                y1 += 1;
                y2 += 1;

                float slope  = (y2 - y1) / (x2 - x1);
                float islope = (x2 - x1) / (y2 - y1);

                float m = slope;
                float w = lineWidth;

                float dx = x2 - x1;
                float dy = y2 - y1;

                float xtot = (float)(w * dy / Math.Sqrt(dx * dx + dy * dy));
                float ytot = (float)(w * dx / Math.Sqrt(dx * dx + dy * dy));

                float sm = dx * dy / (dx * dx + dy * dy);

                // Center it.

                x1 += xtot / 2;
                y1 -= ytot / 2;
                x2 += xtot / 2;
                y2 -= ytot / 2;

                //
                //

                float sx = -xtot;
                float sy = +ytot;

                int ix1 = (int)x1;
                int iy1 = (int)y1;

                int ix2 = (int)x2;
                int iy2 = (int)y2;

                int ix3 = (int)(x1 + sx);
                int iy3 = (int)(y1 + sy);

                int ix4 = (int)(x2 + sx);
                int iy4 = (int)(y2 + sy);

                if (lineWidth == 2)
                {
                    if (Math.Abs(dy) < Math.Abs(dx))
                    {
                        if (x1 < x2)
                        {
                            iy3 = iy1 + 2;
                            iy4 = iy2 + 2;
                        }
                        else
                        {
                            iy1 = iy3 + 2;
                            iy2 = iy4 + 2;
                        }
                    }
                    else
                    {
                        ix1 = ix3 + 2;
                        ix2 = ix4 + 2;
                    }
                }

                int starty = Math.Min(Math.Min(iy1, iy2), Math.Min(iy3, iy4));
                int endy   = Math.Max(Math.Max(iy1, iy2), Math.Max(iy3, iy4));

                if (starty < 0)
                {
                    starty = -1;
                }
                if (endy >= height)
                {
                    endy = height + 1;
                }

                for (int y = starty + 1; y < endy - 1; y++)
                {
                    leftEdgeX[y]  = -1 << 16;
                    rightEdgeX[y] = 1 << 16 - 1;
                }


                AALineQ1(width, height, context, ix1, iy1, ix2, iy2, color, sy > 0, false);
                AALineQ1(width, height, context, ix3, iy3, ix4, iy4, color, sy < 0, true);

                if (lineWidth > 1)
                {
                    AALineQ1(width, height, context, ix1, iy1, ix3, iy3, color, true, sy > 0);
                    AALineQ1(width, height, context, ix2, iy2, ix4, iy4, color, false, sy < 0);
                }

                if (x1 < x2)
                {
                    if (iy2 >= 0 && iy2 < height)
                    {
                        rightEdgeX[iy2] = Math.Min(ix2, rightEdgeX[iy2]);
                    }
                    if (iy3 >= 0 && iy3 < height)
                    {
                        leftEdgeX[iy3] = Math.Max(ix3, leftEdgeX[iy3]);
                    }
                }
                else
                {
                    if (iy1 >= 0 && iy1 < height)
                    {
                        rightEdgeX[iy1] = Math.Min(ix1, rightEdgeX[iy1]);
                    }
                    if (iy4 >= 0 && iy4 < height)
                    {
                        leftEdgeX[iy4] = Math.Max(ix4, leftEdgeX[iy4]);
                    }
                }

                //return;

                for (int y = starty + 1; y < endy - 1; y++)
                {
                    leftEdgeX[y]  = Math.Max(leftEdgeX[y], 0);
                    rightEdgeX[y] = Math.Min(rightEdgeX[y], width - 1);

                    for (int x = leftEdgeX[y]; x <= rightEdgeX[y]; x++)
                    {
                        byte a = (byte)((color & 0xff000000) >> 24);
                        byte r = (byte)((color & 0x00ff0000) >> 16);
                        byte g = (byte)((color & 0x0000ff00) >> 8);
                        byte b = (byte)((color & 0x000000ff) >> 0);

                        Byte rs, gs, bs;
                        Byte rd, gd, bd;

                        Int32 d;

                        rs = r;
                        gs = g;
                        bs = b;

                        d = buffer[y * width + x];

                        rd = (byte)((d & 0x00ff0000) >> 16);
                        gd = (byte)((d & 0x0000ff00) >> 8);
                        bd = (byte)((d & 0x000000ff) >> 0);

                        rd = (byte)((rs * a + rd * (0xff - a)) >> 8);
                        gd = (byte)((gs * a + gd * (0xff - a)) >> 8);
                        bd = (byte)((bs * a + bd * (0xff - a)) >> 8);

                        buffer[y * width + x] = (0xff << 24) | (rd << 16) | (gd << 8) | (bd << 0);
                    }
                }
            }
        }