Ejemplo n.º 1
0
        private unsafe byte[] BitmapToRawIndexed(Bitmap source, int maxColors, out byte[][] palette)
        {
            Bitmap img = source;

            byte[] destination = new byte[img.Width * img.Height];

            // If this is not a 32-bit ARGB bitmap, convert it to one
            if (img.PixelFormat != System.Drawing.Imaging.PixelFormat.Format32bppArgb)
            {
                Bitmap newImage = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(newImage))
                {
                    g.DrawImage(img, 0, 0, img.Width, img.Height);
                }
                img = newImage;
            }

            // Quantize the image
            WuQuantizer quantizer = new WuQuantizer();

            m_palette = quantizer.CreatePalette(img, maxColors);
            img       = (Bitmap)quantizer.QuantizeImage(img, m_palette);

            // Copy over the data to the destination. We need to use Stride in this case, as it may not
            // always be equal to Width.
            BitmapData bitmapData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, img.PixelFormat);

            byte *pointer = (byte *)bitmapData.Scan0;

            for (int y = 0; y < bitmapData.Height; y++)
            {
                for (int x = 0; x < bitmapData.Width; x++)
                {
                    destination[(y * img.Width) + x] = pointer[(y * bitmapData.Stride) + x];
                }
            }

            img.UnlockBits(bitmapData);

            // Copy over the palette
            palette = new byte[maxColors][];
            for (int i = 0; i < maxColors; i++)
            {
                palette[i] = new byte[4];

                palette[i][3] = img.Palette.Entries[i].A;
                palette[i][2] = img.Palette.Entries[i].R;
                palette[i][1] = img.Palette.Entries[i].G;
                palette[i][0] = img.Palette.Entries[i].B;
            }

            return(destination);
        }
Ejemplo n.º 2
0
        public RSImage(string filename, out Exception ex)
        {
            try
            {
                Bitmap bmp = new Bitmap(filename, true);
                if (bmp.PixelFormat != System.Drawing.Imaging.PixelFormat.Format32bppArgb)
                {
                    bmp.MakeTransparent(Color.Transparent);                     //force bmp to be 32-bit
                }
                WuQuantizer q = new WuQuantizer();
                bmp = new Bitmap(q.QuantizeImage(bmp));
                QuantizedPalette p = q.Palette;
                Palette = new Color[p.Colors.Count];
                for (int i = 0; i < p.Colors.Count; i++)
                {
                    Palette[i] = p.Colors[i];
                }

                Pixels = new Color[bmp.Width * bmp.Height];
                for (int i = 0; i < bmp.Width * bmp.Height; i++)
                {
                    Pixels[i] = bmp.GetPixel(i % bmp.Width, i / bmp.Width);
                }
                WholeWidth  = Width = bmp.Width;
                WholeHeight = Height = bmp.Height;
                XOffset     = 0;
                YOffset     = 0;

                ex = null;
            }
            catch (Exception e)
            {
                ex     = e;
                Pixels = null;
            }
        }
Ejemplo n.º 3
0
        protected unsafe byte[] BitmapToRawIndexedResized(Bitmap source, int size, int minSize, QuantizedPalette palette)
        {
            if (size > minSize)
            {
                minSize = size;
            }

            byte[] destination = new byte[minSize * minSize * 4];

            // Resize the image
            Bitmap img = new Bitmap(minSize, minSize, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(img))
            {
                using (ImageAttributes attr = new ImageAttributes())
                {
                    attr.SetWrapMode(WrapMode.TileFlipXY);
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.DrawImage(source, new Rectangle(0, 0, size, size), 0, 0, source.Width, source.Height, GraphicsUnit.Pixel, attr);
                }
            }

            // Quantize the image
            WQuantizer.WuQuantizer quantizer = new WQuantizer.WuQuantizer();
            img = (Bitmap)quantizer.QuantizeImage(img, palette);

            // Copy over the data to the destination. We need to use Stride in this case, as it may not
            // always be equal to Width.
            BitmapData bitmapData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, img.PixelFormat);

            byte *pointer = (byte *)bitmapData.Scan0;

            for (int y = 0; y < bitmapData.Height; y++)
            {
                for (int x = 0; x < bitmapData.Width; x++)
                {
                    destination[(y * img.Width) + x] = pointer[(y * bitmapData.Stride) + x];
                }
            }

            img.UnlockBits(bitmapData);
            return(destination);
        }
Ejemplo n.º 4
0
        private void button_ReadImage_Click(object sender, EventArgs e)
        {
            dataGridView_Color.Rows.Clear();
            button_ColorOutput.Enabled  = false;
            button_ColorPalette.Enabled = false;

            OpenFileDialog dlg = new OpenFileDialog();                                           //创建事例
            string         dir = Environment.GetFolderPath(Environment.SpecialFolder.Templates); //指定初始目录

            dlg.InitialDirectory = dir;                                                          //指定初始目录
            dlg.Title            = "图表对话框";
            dlg.ShowReadOnly     = true;                                                         //以只读方式打开
            dlg.ShowHelp         = true;                                                         //显示帮助按钮            ///////
            dlg.Filter           = "图表.jpg|*.jpg|图表.tif|*.tif|图表.bmp|*.bmp|所有文件|*.*";            //文件过滤器,指定打开文件类型
            //dlg.ShowDialog();//打开对话框
            //BMP 文件(*.bmp) | *.bmp | JPEG 文件(*.jpg, *.jpeg) | *.jpg, *.jpeg | PNG 文件(*.png) | *.png | GIF 文件(*.gif) | *.gif | TIFF 文件(*.tiff, *.tif) | *.tiff
            //MessageBox.Show(dlg.Title);//打开消息
            //dlg.Multiselect = true;//是否允许一次打开多个文件
            dlg.Multiselect = false;     //是否允许一次打开多个文件
                                         // if (dlg.ShowDialog() == DialogResult.OK)
                                         //{
            if (dlg.CheckPathExists)     //检查路径是否存在
            {
                if (dlg.CheckFileExists) //检查文件是否存在
                {
                    // if (dlg.ValidateNames)//检查是否有效Win32文件名
                    //  {
                    if (dlg.ShowDialog() == DialogResult.OK)
                    {
                        string s = dlg.FileNames[0];
                        // foreach (string s in dlg.FileNames)
                        //{                                //string fileName = dlg.FileName;
                        //MessageBox.Show("打开文件:" + s);//打开消息对话框

                        bmDraw = new Bitmap(this.pictureBox_Image.Width, this.pictureBox_Image.Height);
                        Bitmap inputimage = (Bitmap)Image.FromFile(s);

                        System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmDraw);

                        double scale_width  = Convert.ToDouble(bmDraw.Width) / inputimage.Width;
                        double scale_height = Convert.ToDouble(bmDraw.Height) / inputimage.Height;
                        double scale        = scale_width;
                        if (scale_width > scale_height)
                        {
                            scale = scale_height;
                        }

                        int       centerx   = bmDraw.Width / 2;
                        int       centery   = bmDraw.Height / 2;
                        int       newWidth  = Convert.ToInt32(inputimage.Width * scale / 2);
                        int       newHeight = Convert.ToInt32(inputimage.Height * scale / 2);
                        Rectangle rg        = new Rectangle(centerx - newWidth, centery - newHeight, newWidth * 2, newHeight * 2);
                        //将bm内rg所指定的区域绘制到bm1
                        g.DrawImage(inputimage, rg);
                        this.pictureBox_Image.Image = bmDraw;

                        //Step 1: Convert the Image to Use an 8-bit Palette

                        var sourcePath = s;
                        if (!File.Exists(sourcePath))
                        {
                            Console.WriteLine("The source file you specified does not exist.");
                            Environment.Exit(1);
                        }

                        var lastDot    = sourcePath.LastIndexOf('.');
                        var targetPath = sourcePath.Insert(lastDot, "-quant");
                        //if(args.Length > 1)
                        //    targetPath = args[1];

                        var quantizer = new WuQuantizer();
                        // QuantizedPalette ColorPalette = new QuantizedPalette();
                        var    bitmap0 = new Bitmap(sourcePath);
                        Bitmap bitmap1 = ConvertTo32bpp(bitmap0);

                        using (var bitmap = bitmap1)
                        //using (var bitmap = new Bitmap(sourcePath))
                        {
                            using (var quantized = quantizer.QuantizeImage(bitmap))
                                Orignialimage = new Bitmap(quantized);
                            palette = quantizer.palette;
                            //quantized.Save(targetPath, ImageFormat.Png);

                            button_ColorPalette.Enabled = true;
                        }
                    }
                }
                // }
            }
        }
        protected override QuantizedPalette GetQuantizedPalette(int colorCount, ColorData data, IEnumerable <Box> cubes, int alphaThreshold)
        {
            if (_targetColorCount > 0)
            {
                colorCount = _targetColorCount;
            }

            int imageSize = data.PixelsCount;

            LookupData lookups = BuildLookups(cubes, data);

            IList <int> quantizedPixels = data.QuantizedPixels;

            for (var index = 0; index < imageSize; ++index)
            {
                var indexParts = BitConverter.GetBytes(quantizedPixels[index]);

                quantizedPixels[index] =
                    lookups.Tags[indexParts[Alpha], indexParts[Red], indexParts[Green], indexParts[Blue]];
            }

            var alphas = new int[colorCount + 1];
            var reds   = new int[colorCount + 1];
            var greens = new int[colorCount + 1];
            var blues  = new int[colorCount + 1];
            var sums   = new int[colorCount + 1];

            var palette = new QuantizedPalette(imageSize);

            IList <Pixel>  pixels       = data.Pixels;
            int            pixelsCount  = data.PixelsCount;
            IList <Lookup> lookupsList  = lookups.Lookups;
            int            lookupsCount = lookupsList.Count;

            Dictionary <int, MappedError> cachedMatches = new Dictionary <int, MappedError>();

            for (int pixelIndex = 0; pixelIndex < pixelsCount; pixelIndex++)
            {
                Pixel pixel = pixels[pixelIndex];
                palette.PixelIndex[pixelIndex] = -1;

                if (pixel.Alpha <= alphaThreshold)
                {
                    continue;
                }

                var x = pixelIndex % _width;
                var y = (pixelIndex - x) / _width;

                if (pixel.Alpha > 1 && _ditherAmount > 0)
                {
                    // Get bayer dithering.
                    var ov = _adjustedPattern[x % 8 + y % 8 * 8] * _ditherAmount;

                    // Check for semi transparent areas
                    if (pixel.Alpha < _ditherThreshold)
                    {
                        ov *= 1.5;

                        // Apply dithering with a magnitude of 2 to the alpha
                        pixel = new Pixel(Fit(pixel.Alpha + ov), pixel.Red, pixel.Green, pixel.Blue);
                    }
                    else
                    {
                        var l = (pixel.Red * _luminance_r + pixel.Blue * _luminance_b + pixel.Green * _luminance_g) * _byteInverted;

                        if (l > 0.05 && l < 0.95)
                        {
                            if (_debug)
                            {
                                // Draw fuchsia on solid dither area
                                pixel = new Pixel(255, 255, 0, 128);
                            }
                            else
                            {
                                // Apply dithering to the color layer
                                pixel = new Pixel(pixel.Alpha, Fit(pixel.Red + ov), Fit(pixel.Green + ov), Fit(pixel.Blue + ov));
                            }
                        }
                    }
                }

                MappedError bestMatch;
                int         argb = pixel.Argb;

                if (!cachedMatches.TryGetValue(argb, out bestMatch))
                {
                    int match = quantizedPixels[pixelIndex];

                    bestMatch = new MappedError
                    {
                        Index = match
                    };

                    int bestDistance = int.MaxValue;

                    for (int lookupIndex = 0; lookupIndex < lookupsCount; lookupIndex++)
                    {
                        Lookup lookup = lookupsList[lookupIndex];

                        var deltaAlpha = pixel.Alpha - lookup.Alpha;
                        var deltaRed   = pixel.Red - lookup.Red;
                        var deltaGreen = pixel.Green - lookup.Green;
                        var deltaBlue  = pixel.Blue - lookup.Blue;

                        // Take luminance into account when calculating color distance (green is always the most percievable, blue is the least).
                        var distance =
                            (int)
                            ((double)deltaAlpha * deltaAlpha * _luminance_a +
                             (double)deltaRed * deltaRed * _luminance_r +
                             (double)deltaGreen * deltaGreen * _luminance_g +
                             (double)deltaBlue * deltaBlue * _luminance_b);

                        if (distance >= bestDistance)
                        {
                            continue;
                        }

                        bestDistance = distance;

                        bestMatch.AlphaError = deltaAlpha;
                        bestMatch.Index      = lookupIndex;
                    }

                    cachedMatches[argb] = bestMatch;
                }

                alphas[bestMatch.Index] += pixel.Alpha;
                reds[bestMatch.Index]   += pixel.Red;
                greens[bestMatch.Index] += pixel.Green;
                blues[bestMatch.Index]  += pixel.Blue;
                sums[bestMatch.Index]++;

                palette.PixelIndex[pixelIndex] = bestMatch.Index;
            }

            for (var paletteIndex = 0; paletteIndex < colorCount; paletteIndex++)
            {
                if (sums[paletteIndex] > 0)
                {
                    alphas[paletteIndex] /= sums[paletteIndex];
                    reds[paletteIndex]   /= sums[paletteIndex];
                    greens[paletteIndex] /= sums[paletteIndex];
                    blues[paletteIndex]  /= sums[paletteIndex];
                }

                var color = Color.FromArgb(alphas[paletteIndex], reds[paletteIndex], greens[paletteIndex], blues[paletteIndex]);
                palette.Colors.Add(color);
            }

            palette.Colors.Add(Color.FromArgb(0, 0, 0, 0));

            return(palette);
        }