Exemplo n.º 1
0
        public Bitmap FloydSteinberg()
        {
            RGBint oldPixel, qErr = new RGBint(); Color newPixel;

            RGBint[,] arr = new RGBint[bmp.Height, bmp.Width];
            for (int i = 0; i < bmp.Height; i++)
            {
                for (int j = 0; j < bmp.Width; j++)
                {
                    arr[i, j] = new RGBint(bmp.GetPixel(j, i).R, bmp.GetPixel(j, i).G, bmp.GetPixel(j, i).B);
                }
            }

            for (int i = 0; i < bmp.Height; i++)
            {
                for (int j = 0; j < bmp.Width; j++)
                {
                    oldPixel = arr[i, j];
                    newPixel = FindColorFromPal((int)oldPixel.Rint, (int)oldPixel.Gint, (int)oldPixel.Bint);
                    bmp.SetPixel(j, i, newPixel);
                    qErr.Set(oldPixel.Rint - newPixel.R, oldPixel.Gint - newPixel.G, oldPixel.Bint - newPixel.B);

                    if (j < bmp.Width - 1)
                    {
                        arr[i, j + 1].Set(arr[i, j + 1].Rint + qErr.Rint * 7 / 16, arr[i, j + 1].Gint + qErr.Gint * 7 / 16, arr[i, j + 1].Bint + qErr.Bint * 7 / 16);
                        if (i < bmp.Height - 1)
                        {
                            arr[i + 1, j + 1].Set(arr[i + 1, j + 1].Rint + qErr.Rint * 1 / 16, arr[i + 1, j + 1].Gint + qErr.Gint * 1 / 16, arr[i + 1, j + 1].Bint + qErr.Bint * 1 / 16);
                        }
                    }
                    if (i < bmp.Height - 1)
                    {
                        arr[i + 1, j].Set(arr[i + 1, j].Rint + qErr.Rint * 5 / 16, arr[i + 1, j].Gint + qErr.Gint * 5 / 16, arr[i + 1, j].Bint + qErr.Bint * 5 / 16);
                        if (j > 0)
                        {
                            arr[i + 1, j - 1].Set(arr[i + 1, j - 1].Rint + qErr.Rint * 3 / 16, arr[i + 1, j - 1].Gint + qErr.Gint * 3 / 16, arr[i + 1, j - 1].Bint + qErr.Bint * 3 / 16);
                        }
                    }
                }
            }
            return(bmp);
        }
Exemplo n.º 2
0
        public Bitmap FloydSteinberg()
        {
            RGBint old = new RGBint(), qErr = new RGBint();
            Color  c;

            //Locks the bitmap bits
            Rectangle  rect    = new Rectangle(new Point(0, 0), bmp.Size);
            BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);

            //Adress of the first line.
            IntPtr ptr = bmpData.Scan0;

            //Declare array to hold the values.
            int bpp = Bitmap.GetPixelFormatSize(bmp.PixelFormat) / 8;
            int bmpWidth = bmp.Width, bmpHeight = bmp.Height;
            int stride = Math.Abs(bmpData.Stride);
            int bytes  = stride * bmp.Height;

            byte[] rgbValues = new byte[bytes];

            //Copy values to array.
            Marshal.Copy(ptr, rgbValues, 0, bytes);

            //Create copy with float type.
            double[] rgbValuesFloat = Array.ConvertAll <byte, double>(rgbValues, new Converter <byte, double>(ByteToDouble));

            for (int i = 0; i < bmp.Height; i++)
            {
                for (int j = 0; j < Math.Ceiling((double)stride / bpp); j++)
                {
                    if (j < bmpWidth)
                    {
                        int currentRowCol = i * stride + j * bpp;
                        old.Set(rgbValuesFloat[currentRowCol + 2], rgbValuesFloat[currentRowCol + 1], rgbValuesFloat[currentRowCol]);
                        c = FindColorFromPal((int)old.Rint, (int)old.Gint, (int)old.Bint);
                        //Set new pixel value.
                        rgbValuesFloat[currentRowCol + 2] = c.R; rgbValuesFloat[currentRowCol + 1] = c.G; rgbValuesFloat[currentRowCol] = c.B;
                        qErr.Set(old.Rint - c.R, old.Gint - c.G, old.Bint - c.B);
                        if (j < bmpWidth - 1)
                        {
                            rgbValuesFloat[currentRowCol + bpp + 2] = rgbValuesFloat[currentRowCol + bpp + 2] + qErr.Rint * 7 / 16;
                            rgbValuesFloat[currentRowCol + bpp + 1] = rgbValuesFloat[currentRowCol + bpp + 1] + qErr.Gint * 7 / 16;
                            rgbValuesFloat[currentRowCol + bpp]     = rgbValuesFloat[currentRowCol + bpp] + qErr.Bint * 7 / 16;
                            if (i < bmpHeight - 1)
                            {
                                rgbValuesFloat[currentRowCol + stride + bpp + 2] = rgbValuesFloat[currentRowCol + stride + bpp + 2] + qErr.Rint * 1 / 16;
                                rgbValuesFloat[currentRowCol + stride + bpp + 1] = rgbValuesFloat[currentRowCol + stride + bpp + 1] + qErr.Gint * 1 / 16;
                                rgbValuesFloat[currentRowCol + stride + bpp]     = rgbValuesFloat[currentRowCol + stride + bpp] + qErr.Bint * 1 / 16;
                            }
                        }
                        if (i < bmpHeight - 1)
                        {
                            rgbValuesFloat[currentRowCol + stride + 2] = rgbValuesFloat[currentRowCol + stride + 2] + qErr.Rint * 5 / 16;
                            rgbValuesFloat[currentRowCol + stride + 1] = rgbValuesFloat[currentRowCol + stride + 1] + qErr.Gint * 5 / 16;
                            rgbValuesFloat[currentRowCol + stride]     = rgbValuesFloat[currentRowCol + stride] + qErr.Bint * 5 / 16;
                            if (j > 0)
                            {
                                rgbValuesFloat[currentRowCol + stride - bpp + 2] = rgbValuesFloat[currentRowCol + stride - bpp + 2] + qErr.Rint * 3 / 16;
                                rgbValuesFloat[currentRowCol + stride - bpp + 1] = rgbValuesFloat[currentRowCol + stride - bpp + 1] + qErr.Gint * 3 / 16;
                                rgbValuesFloat[currentRowCol + stride - bpp]     = rgbValuesFloat[currentRowCol + stride - bpp] + qErr.Bint * 3 / 16;
                            }
                        }
                    }
                }
            }

            //Convert back.
            rgbValues = Array.ConvertAll <double, byte>(rgbValuesFloat, new Converter <double, byte>(DoubleToByte));

            //Copy them back.
            Marshal.Copy(rgbValues, 0, ptr, bytes);

            //Unlock the bits.
            bmp.UnlockBits(bmpData);

            return(bmp);
        }