コード例 #1
0
        public static void Recolor(this LocklessBitmap bitmap, float r, float g, float b)
        {
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    Color pixel = bitmap.GetPixel(x, y);

                    byte rPixel = pixel.R;
                    byte gPixel = pixel.G;
                    byte bPixel = pixel.B;

                    if (r != 0)
                    {
                        rPixel = (byte)Math.Min((1 - r) * pixel.R, 255);
                    }
                    if (g != 0)
                    {
                        gPixel = (byte)Math.Min((1 - g) * pixel.G, 255);
                    }
                    if (b != 0)
                    {
                        bPixel = (byte)Math.Min((1 - b) * pixel.B, 255);
                    }

                    bitmap.SetPixel(x, y, Color.FromArgb(pixel.A, rPixel, gPixel, bPixel));
                }
            }
        }
コード例 #2
0
 public void Copy(LocklessBitmap bitmap, Rectangle area)
 {
     for (int y = 0; y < area.Height; y++)
     {
         for (int x = 0; x < area.Width; x++)
         {
             SetPixel(x + area.X, y + area.Y, bitmap.GetPixel(x, y));
         }
     }
 }
コード例 #3
0
        public static void SetToGrayscale(this LocklessBitmap bitmap)
        {
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    int grayscale = bitmap.GetGrayscale(x, y);

                    bitmap.SetPixel(x, y, Color.FromArgb(bitmap.GetPixel(x, y).A, grayscale, grayscale, grayscale));
                }
            }
        }
コード例 #4
0
        public LocklessBitmap Rotate(int angle)
        {
            LocklessBitmap rotated = null;

            switch (angle)
            {
            case 0:
                rotated = new LocklessBitmap(Width, Height);
                for (int x = 0; x < rotated.Width; x++)
                {
                    for (int y = 0; y < rotated.Height; y++)
                    {
                        rotated.SetPixel(x, y, GetPixel(x, y));
                    }
                }
                break;

            case 180:
                rotated = new LocklessBitmap(Width, Height);
                for (int x = 0; x < rotated.Width; x++)
                {
                    for (int y = 0; y < rotated.Height; y++)
                    {
                        rotated.SetPixel(x, y, GetPixel((Width - 1) - x, (Height - 1) - y));
                    }
                }
                break;

            case 90:
                rotated = new LocklessBitmap(Height, Width);
                for (int y = 0; y < rotated.Height; y++)
                {
                    for (int x = 0; x < rotated.Width; x++)
                    {
                        rotated.SetPixel(x, y, GetPixel(y, (Height - 1) - x));
                    }
                }
                break;

            case -90:
                rotated = new LocklessBitmap(Height, Width);
                for (int y = 0; y < rotated.Height; y++)
                {
                    for (int x = 0; x < rotated.Width; x++)
                    {
                        rotated.SetPixel(x, y, GetPixel((Width - 1) - y, x));
                    }
                }
                break;
            }

            return(rotated);
        }
コード例 #5
0
ファイル: ImageHelper.cs プロジェクト: pephek/EscherPublic
        public static Bitmap Measure(this Image image, byte threshold, string perforation, out string size)
        {
            LocklessBitmap bitmap = new LocklessBitmap(image.Width, image.Height);

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

            size = SizeHelper.Measure(bitmap, SizeHelper.GetPerforations(perforation), threshold);

            return(bitmap.Bitmap);
        }
コード例 #6
0
ファイル: ImageHelper.cs プロジェクト: pephek/EscherPublic
        public static Bitmap Blacken(this Image image, byte threshold)
        {
            LocklessBitmap blackendBitmap = new LocklessBitmap(image.Width, image.Height);

            using (Graphics graphics = Graphics.FromImage(blackendBitmap.Bitmap))
            {
                graphics.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height));
            }

            blackendBitmap.Blacken(threshold);

            return(blackendBitmap.Bitmap);
        }
コード例 #7
0
ファイル: ImageHelper.cs プロジェクト: pephek/EscherPublic
        public static Bitmap Recolor(this Image image, float r, float g, float b)
        {
            LocklessBitmap recoloredBitmap = new LocklessBitmap(image.Width, image.Height);

            using (Graphics graphics = Graphics.FromImage(recoloredBitmap.Bitmap))
            {
                graphics.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height));
            }

            recoloredBitmap.Recolor(r, g, b);

            return(recoloredBitmap.Bitmap);
        }
コード例 #8
0
        public LocklessBitmap Copy(Rectangle area)
        {
            LocklessBitmap copy = new LocklessBitmap(area.Width, area.Height);

            for (int y = 0; y < area.Height; y++)
            {
                for (int x = 0; x < area.Width; x++)
                {
                    copy.SetPixel(x, y, GetPixel(x + area.X, y + area.Y));
                }
            }

            return(copy);
        }
コード例 #9
0
ファイル: ImageHelper.cs プロジェクト: pephek/EscherPublic
        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);
        }
コード例 #10
0
        public static void Blacken(this LocklessBitmap bitmap, byte threshold)
        {
            for (int y = 0; y < bitmap.Height; y++)
            {
                int x = 0;

                while (x <= bitmap.Width - 1 && bitmap.GetGrayscale(x, y) <= threshold)
                {
                    bitmap.SetPixel(x, y, Color.FromArgb(bitmap.GetPixel(x, y).A, 0, 0, 0));
                    x++;
                }

                x = bitmap.Width - 1;

                while (x >= 0 && bitmap.GetGrayscale(x, y) <= threshold)
                {
                    bitmap.SetPixel(x, y, Color.FromArgb(bitmap.GetPixel(x, y).A, 0, 0, 0));
                    x--;
                }
            }

            for (int x = 0; x < bitmap.Width; x++)
            {
                int y = 0;

                while (y <= bitmap.Height - 1 && bitmap.GetGrayscale(x, y) <= threshold)
                {
                    bitmap.SetPixel(x, y, Color.FromArgb(bitmap.GetPixel(x, y).A, 0, 0, 0));
                    y++;
                }

                y = bitmap.Height - 1;

                while (y >= 0 && bitmap.GetGrayscale(x, y) <= threshold)
                {
                    bitmap.SetPixel(x, y, Color.FromArgb(bitmap.GetPixel(x, y).A, 0, 0, 0));
                    y--;
                }
            }
        }
コード例 #11
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);
        }