Изображение C # в двоичное изображение - замена пикселей на растровые изображения 1 и 0 - PullRequest
0 голосов
/ 25 сентября 2019

В настоящее время я пытаюсь преобразовать растровое изображение в двоичное изображение.Я беру среднее значение пикселя, и если оно ниже определенного порога, пиксель будет либо 1, либо 0. Я знаю, как заставить это работать с текстовым файлом.Но я пытаюсь создать образ из нулей и единиц.Таким образом, каждый пиксель будет преобразован в растровое изображение 8x8.Это работает ... вроде, но получающиеся изображения деформированы и наклонены.

Это код, который я сейчас использую:

        private static Bitmap CreateBinaryImage(Bitmap zero, Bitmap one, Bitmap source)
        {
            // store all results and their location here
            var imageList = new List<KeyValuePair<Point, Bitmap>>();
            // new width and height
            int w = source.Width  * zero.Width;
            int h = source.Height * zero.Height;
            // width and height of binary image
            int hbin = zero.Height;
            int wbin = zero.Width;
            // image position indexer
            int posX = 0;
            int posY = 0;
            // bitmap to draw on
            var canvas = new Bitmap(w, h, source.PixelFormat);
            unsafe
            {
                BitmapData lockBits = source.LockBits(
                    new Rectangle(0, 0, source.Width, source.Height),
                    ImageLockMode.ReadWrite,
                    source.PixelFormat);

                try
                {                        
                    // byte per pixel
                    int bpp = Bitmap.GetPixelFormatSize(source.PixelFormat) / 8;
                    int hip = lockBits.Height;
                    int wib = lockBits.Width;
                    // pointer to first pixel
                    byte* ptrPx = (byte*)lockBits.Scan0;
                    // length of stride
                    int bytes = Math.Abs(lockBits.Stride);
                    for (int y = 0; y < hip; y++)
                    {
                        // get pointer to current scanline
                        byte* scanLine = ptrPx + y * bytes;
                        // iterate through pixels
                        for (int x = 0; x < bytes; x += bpp)
                        {
                            // calculate average to determine if pixel will be 1 or 0
                            float avg = ((scanLine[x + 2] & 0xff) / 255f +
                                         (scanLine[x + 1] & 0xff) / 255f +
                                         (scanLine[x    ] & 0xff) / 255f) / 3;
                            avg = Math.Min(1f, .35f + .65f * avg);

                            // set location and bitmap which will later be drawn
                            imageList.Add(new KeyValuePair<Point, Bitmap>(
                                new Point(posX, posY), 
                                avg < 0.53f ? one : zero));

                            // increment or decrement the binary image location variables
                            posX += wbin;
                            if (posX > w)
                            {
                                posY += hbin;
                                posX = 0;
                            }
                        }
                    }

                    using (var g = Graphics.FromImage(canvas))
                    {
                        // draw images on canvas bitmap
                        for (int i = 0; i < imageList.Count; i++)
                        {
                            g.DrawImage(imageList[i].Value, imageList[i].Key);
                        }
                    }
                }
                finally
                {
                    // release locked bits
                    if (source != null) {
                        source.UnlockBits(lockBits);
                    }
                }
                return canvas;
            }
        }

И результаты выглядят как this или это (исходное изображение слева и двоичное изображение справа)

Я просто не понимаю, что я делаю неправильно ...

Здесьявляется основным между прочим:

        static void Main(string[] args)
        {        
            var source = (Bitmap)Load.FromFile("c:\\dir\\...\\some_image_to_convert.jpeg");
            var zero   = (Bitmap)Load.FromFile("c:\\dir\\...\\bin_0_8px.png");
            var one    = (Bitmap)Load.FromFile("c:\\dir\\...\\bin_1_8px.png");

            var binaryImage = CreateBinaryImage(zero, one, source);
            binaryImage.Save("c:\\dir\\...\\desktop\\binaryImage_test.jpeg");

            Console.Write("Done... Press any key to exit");
            Console.ReadKey();
        }
...