示例#1
0
        public static Image GetSelection(this Image image, Rectangle selection, bool convertToGrayscale)
        {
            LocklessBitmap bitmap = new LocklessBitmap(selection.Width, selection.Height);

            using (Graphics graphics = Graphics.FromImage(bitmap.Bitmap))
            {
                //graphics.DrawImage(new Bitmap(image), new Rectangle(0, 0, selection.Width, selection.Height), selection, GraphicsUnit.Pixel);
                graphics.DrawImage(image, new Rectangle(0, 0, selection.Width, selection.Height), selection, GraphicsUnit.Pixel);
            }

            if (convertToGrayscale)
            {
                bitmap.SetToGrayscale();
            }

            return(bitmap.Bitmap);
        }
示例#2
0
        public static string Measure(LocklessBitmap bitmap, float[] perf, byte threshold)
        {
            int width  = bitmap.Width;
            int height = bitmap.Height;

            int xMin = width / 8;
            int xMax = width - xMin;
            int yMin = height / 8;
            int yMax = height - yMin;

            Rectangle[] areas = new Rectangle[]
            {
                new Rectangle(xMin, 0, xMax - xMin, yMin),
                new Rectangle(xMax, yMin, xMin, yMax - yMin),
                new Rectangle(xMin, yMax, xMax - xMin, yMin),
                new Rectangle(0, yMin, xMin, yMax - yMin)
            };

            int[] rotation = new int[] { 0, -90, 180, +90 };

            int[] antiRotation = new int[] { 0, +90, 180, -90 };

            LocklessBitmap[] bitmaps = new LocklessBitmap[]
            {
                bitmap.Copy(areas[(int)Side.Top]).Rotate(rotation[(int)Side.Top]),
                bitmap.Copy(areas[(int)Side.Right]).Rotate(rotation[(int)Side.Right]),
                bitmap.Copy(areas[(int)Side.Bottom]).Rotate(rotation[(int)Side.Bottom]),
                bitmap.Copy(areas[(int)Side.Left]).Rotate(rotation[(int)Side.Left])
            };

            int[] edges = new int[] { 0, 0, 0, 0 };

            float[][] perforations = new float[4][];

            Dictionary <int, float>[] teeth = new Dictionary <int, float> [4];
            Dictionary <int, float>[] holes = new Dictionary <int, float> [4];

            for (int i = (int)Side.Top; i <= (int)Side.Left; i++)
            {
                LocklessBitmap b = bitmaps[i];

                teeth[i] = new Dictionary <int, float>();
                holes[i] = new Dictionary <int, float>();

                perforations[i] = new float[0];

                for (int y = 0; y < b.Height; y++)
                {
                    for (int x = 0; x < b.Width; x++)
                    {
                        b.SetPixel(x, y, b.GetGrayscale(x, y) <= threshold ? Color.Black : Color.White);
                    }
                }

                bool removed = true;

                while (removed)
                {
                    removed = false;

                    for (int y = 1; y < b.Height - 1; y++)
                    {
                        for (int x = 1; x < b.Width - 1; x++)
                        {
                            Color otherColor = b.IsColor(x, y, Color.Black) ? Color.White : Color.Black;

                            int otherCount = 0;

                            for (int dx = -1; dx <= +1; dx++)
                            {
                                for (int dy = -1; dy <= +1; dy++)
                                {
                                    if (!(dx == 0 && dy == 0))
                                    {
                                        if (b.IsColor(x + dx, y + dy, otherColor))
                                        {
                                            otherCount++;
                                        }
                                    }
                                }
                            }

                            if (otherCount >= 6)
                            {
                                b.SetPixel(x, y, otherColor);

                                removed = true;
                            }
                        }
                    }
                }

                int y1, y2;

                y1 = 0;
                while (y1 < b.Height && b.IsColor(0, y1, b.Width - 1, y1, Color.Black, 0.90F))
                {
                    y1++;
                }

                if (!(y1 > 0 && y1 < b.Height))
                {
                    continue; // Not found the upper bound, so continue with the next side
                }

                y2 = y1;
                while (y2 < b.Height && !b.IsColor(0, y2, b.Width - 1, y2, Color.White, 1))
                {
                    y2++;
                }

                if (!(y2 > y1 && y2 < b.Height))
                {
                    continue; // Not found the lower bound, so continue with the next side
                }

                for (int x = 1; x < b.Width - 1; x++) // Iterate from +1 to Width-2 because of the pixel removal !!!
                {
                    for (int y = y2; y > y1; y--)
                    {
                        if (!b.IsColor(x, y, Color.White))
                        {
                            for (int yy = y; yy > y1; yy--)
                            {
                                b.SetPixel(x, yy, Color.Black);
                            }

                            break;
                        }
                    }
                }

                perforations[i] = new float[b.Width - 2];

                float[] perfs = perforations[i];

                for (int x = 1; x < b.Width - 1; x++) // Iterate from +1 to Width-2 because of the pixel removal which not done at the side !!!
                {
                    for (int y = y1; y <= y2; y++)
                    {
                        if (b.IsColor(x, y, Color.White))
                        {
                            perfs[x - 1] = y;

                            break;
                        }
                        else
                        {
                            b.SetPixel(x, y, Color.LightGray);
                        }
                    }
                }

                for (int m = 1; m <= 25; m++)
                {
                    if (m % 2 == 0)
                    {
                        for (int p = 1; p < perfs.Length - 1; p++)
                        {
                            perfs[p] = (perfs[p - 1] + perfs[p] + perfs[p + 1]) / 3;
                        }
                    }
                    else
                    {
                        for (int p = perfs.Length - 2; p >= 1; p--)
                        {
                            perfs[p] = (perfs[p - 1] + perfs[p] + perfs[p + 1]) / 3;
                        }
                    }
                }

                teeth[i] = new Dictionary <int, float>();
                holes[i] = new Dictionary <int, float>();

                for (int p = 1; p < perfs.Length - 1; p++)
                {
                    if (perfs[p] < perfs[p - 1] && perfs[p] < perfs[p + 1])
                    {
                        teeth[i].Add(p, perfs[p]);
                    }
                    if (perfs[p] > perfs[p - 1] && perfs[p] > perfs[p + 1])
                    {
                        holes[i].Add(p, perfs[p]);
                    }
                }

                for (int x = 1; x < b.Width - 1; x++)
                {
                    int y = (int)perfs[x - 1];
                    b.SetPixels(x, y - 1, x, y + 1, Color.Blue);
                }

                edges[i] = y1;
            }

            int widthInPixels  = 0;
            int heightInPixels = 0;

            int top    = edges[(int)Side.Top];
            int right  = edges[(int)Side.Right] != 0 ? bitmap.Width - edges[(int)Side.Right] - 1 : 0;
            int bottom = edges[(int)Side.Bottom] != 0 ? bitmap.Height - edges[(int)Side.Bottom] - 1 : 0;
            int left   = edges[(int)Side.Left];

            if (left != 0 && right != 0)
            {
                widthInPixels = right - left;
            }

            if (top != 0 && bottom != 0)
            {
                heightInPixels = bottom - top;
            }

            for (int i = (int)Side.Top; i <= (int)Side.Left; i++)
            {
                bitmaps[i] = bitmap.Copy(areas[i]).Rotate(rotation[i]);

                LocklessBitmap b = bitmaps[i];

                b.SetToGrayscale();

                int thickness = 0;

                if (edges[i] != 0)
                {
                    b.SetPixels(0, edges[i] - thickness, b.Width - 1, edges[i] + thickness, Color.Red);
                }

                if (teeth[i].Count() != 0)
                {
                    foreach (KeyValuePair <int, float> t in teeth[i])
                    {
                        int y = (int)Math.Round((double)t.Value);

                        b.SetPixels(t.Key - thickness, 0, t.Key + thickness, y, Color.Yellow);
                    }
                }
                if (holes[i].Count() != 0)
                {
                    foreach (KeyValuePair <int, float> h in holes[i])
                    {
                        int y = (int)Math.Round((double)h.Value);

                        b.SetPixels(h.Key - thickness, y, h.Key + thickness, b.Height - 1, Color.Blue);
                    }
                }
                if (perforations[i].Length != 0)
                {
                    for (int x = 1; x < b.Width - 1; x++)
                    {
                        int y = (int)Math.Round((double)perforations[i][x - 1]);

                        b.SetPixels(x, y - thickness, x, y + thickness, Color.Magenta);
                    }
                }

                bitmap.Copy(bitmaps[i].Rotate(antiRotation[i]), areas[i]);
            }

            float[] sizes = new float[4] {
                0, 0, 0, 0
            };

            for (int i = (int)Side.Top; i <= (int)Side.Left; i++)
            {
                if (teeth[i].Count >= 5 && holes[i].Count >= 5)
                {
                    int teethFirst = teeth[i].First().Key;
                    int teethLast  = teeth[i].Last().Key;

                    int   teethPixels = teethLast - teethFirst;
                    float teethSize   = 20F / perf[i] * (teeth[i].Count() - 1);

                    int holesFirst = holes[i].First().Key;
                    int holesLast  = holes[i].Last().Key;

                    int   holesPixels = holesLast - holesFirst;
                    float holesSize   = 20F / perf[i] * (holes[i].Count() - 1);

                    float areaSizeInMillimetersBasedOnTeeth = (float)areas[i].Width / teethPixels * teethSize;
                    float areaSizeInMillimetersBasedOnHoles = (float)areas[i].Width / holesPixels * holesSize;

                    int sizeInPixels = (i == 0 || i == 2 ? widthInPixels : heightInPixels);

                    float stampSizeTeeth = (float)sizeInPixels / areas[i].Width * areaSizeInMillimetersBasedOnTeeth;
                    float stampSizeHoles = (float)sizeInPixels / areas[i].Width * areaSizeInMillimetersBasedOnHoles;

                    sizes[i] = (stampSizeTeeth + stampSizeHoles) / 2;
                }
            }

            float horizontal =
                sizes[(int)Side.Top] != 0 && sizes[(int)Side.Bottom] != 0 ?
                (sizes[(int)Side.Top] + sizes[(int)Side.Bottom]) / 2 :
                (sizes[(int)Side.Top] != 0 ?
                 sizes[(int)Side.Top] :
                 sizes[(int)Side.Bottom]);

            float vertical =
                sizes[(int)Side.Right] != 0 && sizes[(int)Side.Left] != 0 ?
                (sizes[(int)Side.Right] + sizes[(int)Side.Left]) / 2 :
                (sizes[(int)Side.Right] != 0 ?
                 sizes[(int)Side.Right] :
                 sizes[(int)Side.Left]);

            string size = string.Format(
                "{0} × {1} {2} {3} · {4} × {5} · {6}",
                Math.Round(horizontal, 1), Math.Round(vertical, 1), char.ConvertFromUtf32(0x2190),
                Math.Round(sizes[(int)Side.Top], 1), Math.Round(sizes[(int)Side.Bottom], 1),
                Math.Round(sizes[(int)Side.Right], 1), Math.Round(sizes[(int)Side.Left], 1)
                );

            return(size);
        }