Пример #1
0
 public void FillGrid(Grid g, FillOptions options)
 {
     using (var bitmapWrapper = new BmpPixelSnoop(drawArea))
         using (var textureWrapper = options.Texture != null ? new BmpPixelSnoop(options.Texture) : null)
             Parallel.ForEach(g.GetPolygons(), t => AlgorithmUtils.FillPolygon(t, options, bitmapWrapper, textureWrapper));
     //g.GetPolygons().ForEach(t => AlgorithmUtils.FillPolygon(t, options, bitmapWrapper, textureWrapper));
 }
Пример #2
0
        /// <summary>
        /// Test that GetPixel() works the same way as Bitmap.GetPixel()
        /// </summary>
        /// <param name="bmp">The bitmap to test with</param>
        static void TestGetPixel(Bitmap bmp)
        {
            Console.WriteLine("Testing GetPixel()");

            // Deep copy the bitmap
            var bmpClone = bmp.Clone() as Bitmap;

            // Now create a snoop over the clone and
            // iterate over both and compare each pixel
            //
            using (var snoop = new BmpPixelSnoop(bmpClone))
            {
                for (int j = 0; j != bmp.Height; j++)
                {
                    for (int i = 0; i != bmp.Width; i++)
                    {
                        // Normal Butmap.GetPixel()
                        var p1 = bmp.GetPixel(i, j);

                        // BmpPixelSnoop's GetPixel()
                        var p2 = snoop.GetPixel(i, j);

                        // Are they the same (they should be..)
                        if (p1 != p2)
                        {
                            throw new Exception(string.Format("Pixel at ({0}, {1}) does not match!", i, j));
                        }
                    }
                }
            }

            Console.WriteLine("GetPixel() OK");
        }
Пример #3
0
        private static Bitmap ReduceColorsWithoutCachedBitmap(Options options, ProgressBar progressBar)
        {
            Bitmap reducedImage = new Bitmap(options.OriginalImage);

            using (var reducedWrapper = new BmpPixelSnoop(reducedImage))
            {
                var  random   = new Random();
                bool isChange = true;

                int     k                    = options.ColorsNumber;
                Color[] centroids            = new Color[k];
                (int R, int G, int B)[] sums = new (int R, int G, int B)[k];
Пример #4
0
        public static Bitmap ReduceColors(Options options, ProgressBar progressBar)
        {
            var    filter       = GetFilter(options.EDDFiler);
            Bitmap reducedImage = new Bitmap(options.OriginalImage);//new Bitmap(originalImage.Width, originalImage.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            //using (BmpPixelSnoop originalWrapper = new BmpPixelSnoop(originalImage))
            using (BmpPixelSnoop reducedWrapper = new BmpPixelSnoop(reducedImage))
            {
                for (int i = 0; i < reducedImage.Width; i++)
                {
                    for (int j = 0; j < reducedImage.Height; j++)
                    {
                        var originalImagePixel = reducedWrapper.GetPixel(i, j);
                        var r = (int)Approximate(originalImagePixel.R, options.RNumber);
                        var g = (int)Approximate(originalImagePixel.G, options.GNumber);
                        var b = (int)Approximate(originalImagePixel.B, options.BNumber);
                        reducedWrapper.SetPixel(i, j, Color.FromArgb(r, g, b));

                        double errorR = originalImagePixel.R - r;
                        double errorG = originalImagePixel.G - g;
                        double errorB = originalImagePixel.B - b;

                        int f_x = filter.GetLength(0) / 2;
                        int f_y = filter.GetLength(1) / 2;

                        for (int ii = -f_x; ii <= f_x; ii++)
                        {
                            if (i + ii >= reducedImage.Width || i + ii < 0)
                            {
                                continue;
                            }
                            for (int jj = -f_y; jj <= f_y; jj++)
                            {
                                if (j + jj >= reducedImage.Height || j + jj < 0)
                                {
                                    continue;
                                }
                                var colorToSet = reducedWrapper.GetPixel(i + ii, j + jj);
                                colorToSet = Color.FromArgb(
                                    CutTo_0_255(colorToSet.R + (errorR * filter[f_x + ii, f_y + jj])),
                                    CutTo_0_255(colorToSet.G + (errorG * filter[f_x + ii, f_y + jj])),
                                    CutTo_0_255(colorToSet.B + (errorB * filter[f_x + ii, f_y + jj])));
                                reducedWrapper.SetPixel(i + ii, j + jj, colorToSet);
                            }
                        }
                    }
                    progressBar.Value = (int)((i * progressBar.Maximum) / (double)reducedImage.Width);
                }
            }
            progressBar.Value = progressBar.Maximum;
            return(reducedImage);
        }
Пример #5
0
        /// <summary>
        /// Test that SetPixel() works the same way as Bitmap.SetPixel()
        /// </summary>
        /// <param name="bmp">The bitmap to test with</param>
        static void TestSetPixel(Bitmap bmp)
        {
            Console.WriteLine("Testing SetPixel()");

            // Create an empty target bitmap
            // PixelFormat.Format32bppArgb is the default format
            var bmpTarget = new Bitmap(bmp.Width, bmp.Height);

            // We get each pixel from the input bitmap and
            // set to the corresponding pixel in the snooped bitmap.
            // Then we read back this pixel and check that it equals the
            // original pixel value.
            //
            using (var snoop = new BmpPixelSnoop(bmpTarget))
            {
                for (int j = 0; j != bmp.Height; j++)
                {
                    for (int i = 0; i != bmp.Width; i++)
                    {
                        // Get a pixel from the input bitmap
                        var p1 = bmp.GetPixel(i, j);

                        // Set it into the snooped bitmap
                        snoop.SetPixel(i, j, p1);

                        // Read it back from the snooped bitmap
                        var p2 = snoop.GetPixel(i, j);

                        // And compare with original.
                        if (p1 != p2)
                        {
                            throw new Exception(string.Format("Pixel at ({0}, {1}) does not match!", i, j));
                        }
                    }
                }
            }

            // Now test that the snooped bitmap has been released and
            // that we can call SetPixel() on it without an excpetion
            // being thrown...
            //
            try
            {
                bmpTarget.SetPixel(0, 0, System.Drawing.Color.Aqua);
            }
            catch
            {
                throw new Exception(string.Format("Could not write to bitmap, BitmapSnoop did not release it!"));
            }

            Console.WriteLine("SetPixel() OK");
        }
Пример #6
0
        private void openVectorTexture_Click(object sender, EventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();

            dialog.Filter = "image(.png,.jpg)|*.jpg;*.png";
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var texture = new Bitmap(dialog.FileName);
                normalMap = new BmpPixelSnoop(texture.Clone(new Rectangle(0, 0, texture.Width, texture.Height), System.Drawing.Imaging.PixelFormat.Format32bppArgb));
            }
            normal_map_loaded = true;
            drawing_panel.Invalidate();
        }
Пример #7
0
        public static Bitmap ReduceColors(Options options, ProgressBar progressBar)
        {
            Dictionary <(byte R, byte G, byte B), int> colorsPopularity = new Dictionary <(byte R, byte G, byte B), int>();

            var reducedBitmap = new Bitmap(options.OriginalImage);

            using (var reducedWrapper = new BmpPixelSnoop(reducedBitmap))
            {
                for (int i = 0; i < reducedBitmap.Width; i++)
                {
                    for (int j = 0; j < reducedBitmap.Height; j++)
                    {
                        var c = reducedWrapper.GetPixel(i, j);
                        if (!colorsPopularity.TryGetValue((c.R, c.G, c.B), out int cPopularity))
                        {
                            colorsPopularity[(c.R, c.G, c.B)] = 1;
Пример #8
0
        /// <summary>
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        /// <remarks>Only for triangles.</remarks>
        private static Color GetInterpolatedColorForPixel(
            double x1, double y1,
            double x2, double y2,
            double x3, double y3,
            double triangleDenominator, // cout once, use for each pixel
            Vector normalVector1,       // cout once, use for each pixel
            Vector normalVector2,       // cout once, use for each pixel
            Vector normalVector3,       // cout once, use for each pixel
            Color objectColor1,         // cout once, use for each pixel
            Color objectColor2,         // cout once, use for each pixel
            Color objectColor3,         // cout once, use for each pixel
            int x, int y, FillOptions options, BmpPixelSnoop textureWrapper)
        {
            // calculate barycentric coordinates
            double W1 = ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3)) / triangleDenominator;
            double W2 = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) / triangleDenominator;
            double W3 = 1 - W1 - W2;

            Vector N = options.NormalVectorOption == NormalVectorOpt.FromTexture
                ? W1 * normalVector1 + W2 * normalVector2 + W3 * normalVector3  // inerpolated normal vector
                : DEFAULT_OPTIONS.defaultNormalVector;

            Vector V          = new Vector(0, 0, 1);
            var    LightPoint = options.LightPoint;
            var    L          = (options.LightVectorOption == LightVectorOpt.FromPointOnSpiral && LightPoint != null)
                ? new Vector(LightPoint.X - x, (-1) * (LightPoint.Y - y), LightPoint.Z - 0).GetNormalised()
                : DEFAULT_OPTIONS.defaultLightVector;
            Vector R = 2 * Vector.DotProduct(N, L) * N - L;

            Color Il = options.LightColor;
            Color Io = (options.ObjectColorOption == ObjectColorOpt.Constant || options.Texture == null)
                ? (Color)options.ObjectColor
                : Color.FromArgb(
                round_To_0_255((int)(W1 * objectColor1.R + W2 * objectColor2.R + W3 * objectColor3.R)),
                round_To_0_255((int)(W1 * objectColor1.G + W2 * objectColor2.G + W3 * objectColor3.G)),
                round_To_0_255((int)(W1 * objectColor1.B + W2 * objectColor2.B + W3 * objectColor3.B)));     // interpolated object color

            double kd = options.LambertModelFactor;
            double ks = options.ReflectionFactor;
            int    m  = options.ReflectionLevel;

            return(Color.FromArgb(calculatePart(Il.R, Io.R, kd, ks, N, L, V, R, m),
                                  calculatePart(Il.G, Io.G, kd, ks, N, L, V, R, m),
                                  calculatePart(Il.B, Io.B, kd, ks, N, L, V, R, m)));
        }
Пример #9
0
        /// <summary>
        /// Test how fast SetPixel() works compared to Bitmap.SetPixel()
        /// </summary>
        /// <param name="bmp">The bitmap to test with</param>
        static void TestSetPixelSpeed(Bitmap bmp)
        {
            Console.WriteLine("Testing SetPixel() Speed");

            // Deep copy the bitmap
            var bmpClone = bmp.Clone() as Bitmap;

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            // Loop through the bitmap and set each pixel's value
            // to something interesting..
            for (int j = 0; j != bmpClone.Height; j++)
            {
                for (int i = 0; i != bmpClone.Width; i++)
                {
                    var col = Color.FromArgb(i % 255, j % 255, (i + j) % 255, (i * j) % 255);
                    bmpClone.SetPixel(i, j, col);
                }
            }

            var time = stopwatch.ElapsedMilliseconds;

            stopwatch.Reset();
            stopwatch.Start();

            // Now do the same on the snooped bitmap..
            using (var snoop = new BmpPixelSnoop(bmpClone))
            {
                for (int j = 1; j != snoop.Height; j++)
                {
                    for (int i = 0; i != snoop.Width; i++)
                    {
                        var col = Color.FromArgb(i % 255, j % 255, (i * j) % 255, (i + j) % 255);
                        snoop.SetPixel(i, j, col);
                    }
                }
            }

            var snoopTime = stopwatch.ElapsedMilliseconds;

            Console.WriteLine(string.Format("Bitmap.SetPixel() took {0}ms, BmpPixelSnoop.SetPixel() took {1}ms", time, snoopTime));
        }
Пример #10
0
        private void drawing_panel_Paint(object sender, PaintEventArgs e)
        {
            //foreach (var tri in triangles_net)
            Bitmap tmp = new Bitmap(drawing_panel.Width, drawing_panel.Height);

            tmpPicture = new BmpPixelSnoop(tmp);
            Parallel.ForEach(triangles_net, (Polygon tri) =>
                             // foreach (var tri in triangles_net)
            {
                if (!moving)
                {
                    if (aproximate.Checked)
                    {
                        FillFigureAprox(tri, Ks, Kd, M);
                    }
                    else if (hybrid.Checked)
                    {
                        FillFigureHybrid(tri, Ks, Kd, M);
                    }
                    else
                    {
                        FillFigure(tri, Ks, Kd, M);
                    }
                }
            });
            tmpPicture.Dispose();
            e.Graphics.DrawImage(tmp, 0, 0);
            tmp.Dispose();
            foreach (var tri in triangles_net)
            {
                foreach (var edge in tri.edges)
                {
                    DrawLine(edge, e.Graphics);
                }
            }
            //foreach (var point in tri.vertices)
            //{
            //    DrawVertice(point.Get(), e.Graphics);
            //}
        }
Пример #11
0
        private static Vector getNormalVectorFromTexture(int x, int y, FillOptions options, BmpPixelSnoop textureWrapper)
        {
            if (textureWrapper == null)
            {
                return(DEFAULT_OPTIONS.defaultNormalVector);
            }
            var vector = textureWrapper.GetPixel(x - (int)(options.GridLeft), y - (int)(options.GridTop));

            return(new Vector(scaleToNormalVector(vector.R), scaleToNormalVector(vector.G), scale_Form_0_255_To_0_1(vector.B)).GetNormalised());

            double scaleToNormalVector(int c)
            {
                var ret = ((double)c / 255) * 2 - 1;

                if (ret > 1)
                {
                    return(1);
                }
                if (ret < -1)
                {
                    return(-1);
                }
                return(ret);
            }
        }
Пример #12
0
        public static void FillPolygon(Polygon polygon, FillOptions options, BmpPixelSnoop bitmapWrapper, BmpPixelSnoop textureWrapper)
        {
            #region prepare data for interpolation if needed
            double x1 = 1, y1 = 1;
            double x2 = 1, y2 = 1;
            double x3 = 1, y3 = 1;
            double triangleDenominator = 1;
            Vector normalVector1       = null;
            Vector normalVector2       = null;
            Vector normalVector3       = null;
            Color  objectColor1        = Color.FromArgb(1, 1, 1);
            Color  objectColor2        = Color.FromArgb(1, 1, 1);
            Color  objectColor3        = Color.FromArgb(1, 1, 1);

            if (options.FillColorPrecisionOption == FillColorPrecisionOpt.Interpolated)
            {
                // assume polygon is a traingle
                if (polygon.Vertices.Count != 3)
                {
                    throw new ArgumentException("Interpolated Presices is possible only for triangles!");
                }

                x1 = polygon.Vertices[0].X; y1 = polygon.Vertices[0].Y;
                x2 = polygon.Vertices[1].X; y2 = polygon.Vertices[1].Y;
                x3 = polygon.Vertices[2].X; y3 = polygon.Vertices[2].Y;

                triangleDenominator = (y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3);
                if (triangleDenominator == 0)
                {
                    triangleDenominator = 1;
                }

                normalVector1 = getNormalVectorFromTexture((int)x1, (int)y1, options, textureWrapper);
                normalVector2 = getNormalVectorFromTexture((int)x2, (int)y2, options, textureWrapper);
                normalVector3 = getNormalVectorFromTexture((int)x3, (int)y3, options, textureWrapper);

                objectColor1 = (options.ObjectColorOption == ObjectColorOpt.Constant || options.Texture == null)
                ? (Color)options.ObjectColor
                : textureWrapper.GetPixel((int)(x1 - options.GridLeft), (int)(y1 - options.GridTop));
                objectColor2 = (options.ObjectColorOption == ObjectColorOpt.Constant || options.Texture == null)
                ? (Color)options.ObjectColor
                : textureWrapper.GetPixel((int)(x2 - options.GridLeft), (int)(y2 - options.GridTop));
                objectColor3 = (options.ObjectColorOption == ObjectColorOpt.Constant || options.Texture == null)
                ? (Color)options.ObjectColor
                : textureWrapper.GetPixel((int)(x3 - options.GridLeft), (int)(y3 - options.GridTop));
            }
            #endregion

            var sortedVertices = polygon.Vertices.ConvertAll(v => v);
            sortedVertices.Sort((a, b) =>
            {
                if (a.Y < b.Y)
                {
                    return(-1);
                }
                if (a.Y == b.Y)
                {
                    return(0);
                }
                return(1);
            });

            var            ind  = sortedVertices.ConvertAll(v => polygon.Vertices.IndexOf(v));
            var            P    = polygon.Vertices;
            double         ymin = P[ind[0]].Y;
            double         ymax = P[ind[ind.Count - 1]].Y;
            int            k    = 0; // current vertex index;
            List <AETItem> AET  = new List <AETItem>();

            // for each scanline
            for (double y = ymin + 1; y <= ymax + 1; y++)
            {
                while (k < ind.Count && y - 1 == P[ind[k]].Y)
                {
                    // previous vertex
                    int pVertInd = ind[k] - 1 >= 0 ? ind[k] - 1 : P.Count - 1;
                    if (P[pVertInd].Y >= P[ind[k]].Y)
                    {
                        // add to AET
                        double dx = (double)(P[pVertInd].X - P[ind[k]].X);
                        double dy = (double)(P[pVertInd].Y - P[ind[k]].Y);
                        if (dy != 0)
                        {
                            AET.Add(new AETItem(P[pVertInd], P[ind[k]], P[ind[k]].X, dx / dy));
                        }
                    }
                    else
                    {
                        // remove from AET
                        AET.RemoveAll(i => i.start == P[pVertInd] && i.end == P[ind[k]]);
                    }

                    // next vertex
                    int nVertInd = ind[k] + 1 < P.Count ? ind[k] + 1 : 0;
                    if (P[nVertInd].Y >= P[ind[k]].Y)
                    {
                        // add to AET
                        double dx = (double)(P[ind[k]].X - P[nVertInd].X);
                        double dy = (double)(P[ind[k]].Y - P[nVertInd].Y);
                        if (dy != 0)
                        {
                            AET.Add(new AETItem(P[ind[k]], P[nVertInd], P[ind[k]].X, dx / dy));
                        }
                    }
                    else
                    {
                        // remove from AET
                        AET.RemoveAll(i => i.start == P[ind[k]] && i.end == P[nVertInd]);
                    }

                    k++;
                }

                // sort by x
                AET.Sort((a, b) =>
                {
                    if (a.x < b.x)
                    {
                        return(-1);
                    }
                    if (a.x == b.x)
                    {
                        return(0);
                    }
                    return(1);
                });

                // set pixels
                for (int i = 0; i < AET.Count - 1; i += 2)
                {
                    for (double x = AET[i].x; x <= AET[i + 1].x; x++)
                    {
                        bitmapWrapper.SetPixel((int)x, (int)y - 1,
                                               options.FillColorPrecisionOption == FillColorPrecisionOpt.Precise
                            ? GetPreciseColorForPixel((int)x, (int)y - 1, options, textureWrapper)
                            : GetInterpolatedColorForPixel(
                                                   (int)x1, (int)y1, (int)x2, (int)y2, (int)x3, (int)y3, triangleDenominator,
                                                   normalVector1, normalVector2, normalVector3,
                                                   objectColor1, objectColor2, objectColor3, (int)x, (int)y - 1, options, textureWrapper));
                    }
                }

                // update x
                AET.ForEach(v => v.x += v.reciprocalM);
            }
        }
Пример #13
0
        private static Color GetPreciseColorForPixel(int x, int y, FillOptions options, BmpPixelSnoop textureWrapper)
        {
            Vector N          = options.NormalVectorOption == NormalVectorOpt.FromTexture ? getNormalVectorFromTexture(x, y, options, textureWrapper) : DEFAULT_OPTIONS.defaultNormalVector;
            Vector V          = new Vector(0, 0, 1);
            var    LightPoint = options.LightPoint;
            var    L          = (options.LightVectorOption == LightVectorOpt.FromPointOnSpiral && LightPoint != null)
                ? new Vector(LightPoint.X - x, (-1) * (LightPoint.Y - y), LightPoint.Z - 0).GetNormalised()
                : DEFAULT_OPTIONS.defaultLightVector;
            Vector R = 2 * Vector.DotProduct(N, L) * N - L;

            Color Il = options.LightColor;
            Color Io = (options.ObjectColorOption == ObjectColorOpt.Constant || options.Texture == null)
                ? (Color)options.ObjectColor
                : textureWrapper.GetPixel(x - (int)(options.GridLeft), y - (int)(options.GridTop));
            double kd = options.LambertModelFactor;
            double ks = options.ReflectionFactor;
            int    m  = options.ReflectionLevel;

            return(Color.FromArgb(calculatePart(Il.R, Io.R, kd, ks, N, L, V, R, m),
                                  calculatePart(Il.G, Io.G, kd, ks, N, L, V, R, m),
                                  calculatePart(Il.B, Io.B, kd, ks, N, L, V, R, m)));
        }
Пример #14
0
        private void ProcessBitmap()
        {
            int usedColors  = 0;
            int totalColors = 0;

            if (texinfo is PvrTextureInfo)
            {
                radioButtonRGB5A3.Enabled = radioButtonIntensity8A.Enabled = false;
            }

            using (var snoop_u = new BmpPixelSnoop(new Bitmap(bitmap)))
            {
                for (int p = 0; p < bitmap.Palette.Entries.Length; p++)
                {
                    totalColors += 1;
                    bool match = false;
                    for (int h = 0; h < bitmap.Height; h++)
                    {
                        for (int w = 0; w < bitmap.Width; w++)
                        {
                            if (snoop_u.GetPixel(w, h) == bitmap.Palette.Entries[p])
                            {
                                match = true;
                            }
                        }
                    }
                    if (match)
                    {
                        usedColors += 1;
                    }
                }
            }
            if (usedColors <= 16)
            {
                radioButtonIndex4.Checked = true;
                radioButtonIndex4.Enabled = true;
            }
            else if (usedColors <= 256)
            {
                radioButtonIndex8.Checked = true;
                radioButtonIndex4.Enabled = false;
            }
            else
            {
                radioButtonIndex4.Enabled     = radioButtonIndex8.Enabled = false;
                radioButtonNonIndexed.Checked = true;
            }
            int    tlevel       = TextureFunctions.GetAlphaLevelFromBitmap(bitmap);
            string transparency = "";

            switch (tlevel)
            {
            case 0:
                radioButtonRGB565.Checked = true;
                transparency = "no transparency";
                break;

            case 1:
                transparency = "1-bit transparency";
                if (SACompatible || !gamecube)
                {
                    radioButtonARGB1555.Checked = true;
                }
                else
                {
                    radioButtonRGB5A3.Checked = true;
                }
                break;

            case 2:
                transparency = "partial transparency";
                if (SACompatible || !gamecube)
                {
                    radioButtonARGB4444.Checked = true;
                }
                else
                {
                    radioButtonRGB5A3.Checked = true;
                }
                break;
            }

            labelPaletteInfo.Text = "Palette: " + totalColors.ToString() + " colors (" + usedColors.ToString() + " colors used) , " + transparency;
            groupBoxMask.Enabled  = groupBoxPalette.Enabled = buttonAuto.Enabled = buttonOK.Enabled = true;
            if (!gamecube)
            {
                radioButtonIntensity8A.Enabled = radioButtonRGB5A3.Enabled = false;
            }
            else
            {
                radioButtonIntensity8A.Enabled = radioButtonRGB5A3.Enabled = true;
            }
        }
Пример #15
0
        /// <summary>
        /// Test how fast GetPixel() works compared to Bitmap.GetPixel()
        /// </summary>
        /// <param name="bmp">The bitmap to test with</param>
        static void TestGetPixelSpeed(Bitmap bmp)
        {
            Console.WriteLine("Testing GetPixel() Speed");

            // Deep copy the bitmap
            var bmpClone = bmp.Clone() as Bitmap;

            // Calculate a simple sum over all of the pixels
            // in the original bitmap.
            long sum = 0;

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            for (int j = 0; j != bmpClone.Height; j++)
            {
                for (int i = 0; i != bmpClone.Width; i++)
                {
                    var col = bmpClone.GetPixel(i, j);

                    sum += col.R +
                           col.G +
                           col.B;
                }
            }

            var time = stopwatch.ElapsedMilliseconds;

            stopwatch.Reset();
            stopwatch.Start();

            long snoopSum = 0;

            // Calculate a simple sum over all of the pixels
            // in the snooped bitmap.
            using (var snoop = new BmpPixelSnoop(bmpClone))
            {
                for (int j = 0; j != snoop.Height; j++)
                {
                    for (int i = 0; i != snoop.Width; i++)
                    {
                        var col = snoop.GetPixel(i, j);

                        snoopSum += col.R +
                                    col.G +
                                    col.B;
                    }
                }
            }

            var snoopTime = stopwatch.ElapsedMilliseconds;

            // Just make sure our sums match
            if (sum != snoopSum)
            {
                throw new Exception("Pixel sums don't match!");
            }

            Console.WriteLine(string.Format("Bitmap.GetPixel() took {0}ms, BmpPixelSnoop.GetPixel() took {1}ms", time, snoopTime));
        }
Пример #16
0
        public override Bitmap GenerateImage(int width, int height, int level)
        {
            double A = d_m[0, 0], B = d_m[1, 0], C = d_m[2, 0], D = d_m[3, 0], E = d_m[0, 1], F = d_m[1, 1],
                   G = d_m[1, 2], H = d_m[1, 3], I = d_m[2, 0], J = d_m[2, 1], K = d_m[2, 2], L = d_m[2, 3],
                   M = d_m[3, 0], N = d_m[3, 1], P = d_m[3, 2], Q = d_m[3, 3];
            double a = K;

            width  = (int)((double)width / (level * level));
            height = (int)((double)height / (level * level));
            Bitmap        resultImage = new Bitmap(width, height);
            BmpPixelSnoop snoop       = new BmpPixelSnoop(resultImage);

            {
                Color lastColor;
                int   x_max = width % 2 == 0 ? width / 2 : width / 2 + 1;
                int   y_max = height % 2 == 0 ? height / 2 : height / 2 + 1;
                for (int x_r = -width / 2; x_r < x_max; x_r++)
                {
                    int x = x_r * level * level;
                    for (int y_r = -height / 2; y_r < y_max; y_r++)
                    {
                        int    y = y_r * level * level;
                        double b = x * I + y * J + x * C + y * G + P + L;
                        double c = x * x * A + x * y * E + x * M + x * y * B +
                                   y * y * F + y * N + x * D + y * H + Q;

                        double delta = b * b - 4 * a * c;

                        if (delta < 0)
                        {
                            lastColor = Color.DarkGray;
                        }
                        else
                        {
                            double z;
                            if (delta == 0)
                            {
                                z = -b / 2 * a;
                            }
                            else
                            {
                                double z1 = (-b - Math.Sqrt(delta)) / (2 * a);
                                double z2 = (-b + Math.Sqrt(delta)) / (2 * a);

                                if (observator_position[2] - z1 < observator_position[2] - z2)
                                {
                                    z = z1;
                                }
                                else
                                {
                                    z = z2;
                                }
                            }
                            Vector <double> normal = Vector <double> .Build.DenseOfArray(
                                new double[] {
                                2 * x * A + y * E + z * I + M + y * B + z * C + D,
                                x *E + x * B + 2 * y * F + z * J + N + z * G + H,
                                x *I + y * J + x * C + y * G + 2 * z * K + P + L
                            }).Normalize(2);

                            Vector <double> to_observer = (observator_position - Vector <double> .Build.DenseOfArray(new double[] { x, y, z })).Normalize(2);

                            double color = to_observer.DotProduct(normal);
                            color = Math.Pow(color, m_col);
                            if (color < 0)
                            {
                                color = 0;
                            }
                            lastColor = Color.FromArgb((byte)(Color.Yellow.R * color), (byte)(Color.Yellow.G * color), (byte)(Color.Yellow.B * color));
                        }
                        snoop.SetPixel(x_r + width / 2, y_r + height / 2, lastColor);
                    }
                }
            }
            return(resultImage);
        }