Пример #1
0
        private static Bitmap ProcessImagePixels(Image sourceImage, QuantizedPalette palette)
        {
            var result     = new Bitmap(sourceImage.Width, sourceImage.Height, PixelFormat.Format8bppIndexed);
            var newPalette = result.Palette;

            for (var index = 0; index < palette.Colors.Count; index++)
            {
                newPalette.Entries[index] = palette.Colors[index];
            }
            result.Palette = newPalette;

            BitmapData targetData = null;

            try
            {
                targetData = result.LockBits(Rectangle.FromLTRB(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, result.PixelFormat);
                const byte targetBitDepth   = 8;
                var        targetByteLength = targetData.Stride < 0 ? -targetData.Stride : targetData.Stride;
                var        targetByteCount  = Math.Max(1, targetBitDepth >> 3);
                var        targetSize       = targetByteLength * result.Height;
                var        targetOffset     = 0;
                var        targetBuffer     = new byte[targetSize];
                var        targetValue      = new byte[targetByteCount];
                var        pixelIndex       = 0;

                for (var y = 0; y < result.Height; y++)
                {
                    var targetIndex = 0;
                    for (var x = 0; x < result.Width; x++)
                    {
                        var targetIndexOffset = targetIndex >> 3;
                        targetValue[0] = (byte)(palette.PixelIndex[pixelIndex] == -1 ? palette.Colors.Count - 1 : palette.PixelIndex[pixelIndex]);
                        pixelIndex++;

                        for (var valueIndex = 0; valueIndex < targetByteCount; valueIndex++)
                        {
                            targetBuffer[targetOffset + valueIndex + targetIndexOffset] = targetValue[valueIndex];
                        }

                        targetIndex += targetBitDepth;
                    }

                    targetOffset += targetByteLength;
                }

                Marshal.Copy(targetBuffer, 0, targetData.Scan0, targetSize);
            }
            finally
            {
                if (targetData != null)
                {
                    result.UnlockBits(targetData);
                }
            }

            return(result);
        }
Пример #2
0
 public Image QuantizeImage(Bitmap image, int alphaThreshold, int alphaFader)
 {
     var colorCount = MaxColor;
     var data = BuildHistogram(image, alphaThreshold, alphaFader);
     data = CalculateMoments(data);
     var cubes = SplitData(ref colorCount, data);
     Palette = GetQuantizedPalette(colorCount, data, cubes, alphaThreshold);
     return ProcessImagePixels(image, Palette);
 }
Пример #3
0
        public Image QuantizeImage(Bitmap image, int alphaThreshold, int alphaFader)
        {
            var colorCount = MaxColor;
            var data       = BuildHistogram(image, alphaThreshold, alphaFader);

            data = CalculateMoments(data);
            var cubes = SplitData(ref colorCount, data);

            Palette = GetQuantizedPalette(colorCount, data, cubes, alphaThreshold);
            return(ProcessImagePixels(image, Palette));
        }
Пример #4
0
        public Image QuantizeImage(Bitmap image)
        {
            var colorCount = MaxColor;
            var data       = BuildHistogram(image);

            data = CalculateMoments(data);
            var cubes = SplitData(ref colorCount, data);

            palette = GetQuantizedPalette(colorCount, data, cubes);
            //var palette = GetQuantizedPalette(colorCount, data, cubes);
            return(ProcessImagePixels(image, palette));
        }
Пример #5
0
        private static Bitmap ProcessImagePixels(Image sourceImage, QuantizedPalette palette)
        {
            var result = new Bitmap(sourceImage.Width, sourceImage.Height, PixelFormat.Format8bppIndexed);
            var newPalette = result.Palette;
            for (var index = 0; index < palette.Colors.Count; index++)
                newPalette.Entries[index] = palette.Colors[index];
            result.Palette = newPalette;

            BitmapData targetData = null;
            try
            {
                targetData = result.LockBits(Rectangle.FromLTRB(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, result.PixelFormat);
                const byte targetBitDepth = 8;
                var targetByteLength = targetData.Stride < 0 ? -targetData.Stride : targetData.Stride;
                var targetByteCount = Math.Max(1, targetBitDepth >> 3);
                var targetSize = targetByteLength * result.Height;
                var targetOffset = 0;
                var targetBuffer = new byte[targetSize];
                var targetValue = new byte[targetByteCount];
                var pixelIndex = 0;

                for (var y = 0; y < result.Height; y++)
                {
                    var targetIndex = 0;
                    for (var x = 0; x < result.Width; x++)
                    {
                        var targetIndexOffset = targetIndex >> 3;
                        targetValue[0] = (byte)(palette.PixelIndex[pixelIndex] == -1 ? palette.Colors.Count - 1 : palette.PixelIndex[pixelIndex]);
                        pixelIndex++;

                        for (var valueIndex = 0; valueIndex < targetByteCount; valueIndex++)
                            targetBuffer[targetOffset + valueIndex + targetIndexOffset] = targetValue[valueIndex];

                        targetIndex += targetBitDepth;
                    }

                    targetOffset += targetByteLength;
                }

                Marshal.Copy(targetBuffer, 0, targetData.Scan0, targetSize);
            }
            finally
            {
                if(targetData != null)
                    result.UnlockBits(targetData);
            }

            return result;
        }
Пример #6
0
        protected override QuantizedPalette GetQuantizedPalette(int colorCount, ColorData data, IEnumerable <Box> cubes, int alphaThreshold)
        {
            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, int> cachedMaches = new Dictionary <int, int>();

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

                int bestMatch;
                int argb = pixel.Argb;

                if (!cachedMaches.TryGetValue(argb, out bestMatch))
                {
                    int match = quantizedPixels[pixelIndex];
                    bestMatch = 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;

                        int distance = deltaAlpha * deltaAlpha + deltaRed * deltaRed + deltaGreen * deltaGreen + deltaBlue * deltaBlue;

                        if (distance >= bestDistance)
                        {
                            continue;
                        }

                        bestDistance = distance;
                        bestMatch    = lookupIndex;
                    }

                    cachedMaches[argb] = bestMatch;
                }

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

                palette.PixelIndex[pixelIndex] = bestMatch;
            }

            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);
        }
Пример #7
0
        private static QuantizedPalette GetQuantizedPalette(int colorCount, ColorData data, IEnumerable <Box> cubes)
        {
            var imageSize = data.Pixels.Count;
            var lookups   = BuildLookups(cubes, data);

            for (var index = 0; index < imageSize; ++index)
            {
                var indexParts = BitConverter.GetBytes(data.QuantizedPixels[index]);
                data.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);
            var index2  = -1;

            foreach (var pixel in data.Pixels)
            {
                palette.PixelIndex[++index2] = -1;
                if (pixel.Alpha <= AlphaThreshold)
                {
                    continue;
                }

                var match        = data.QuantizedPixels[index2];
                var bestMatch    = match;
                var bestDistance = 100000000;
                var index        = -1;

                foreach (var lookup in lookups.Lookups)
                {
                    ++index;
                    var deltaAlpha = pixel.Alpha - lookup.Alpha;
                    var deltaRed   = pixel.Red - lookup.Red;
                    var deltaGreen = pixel.Green - lookup.Green;
                    var deltaBlue  = pixel.Blue - lookup.Blue;

                    var distance = deltaAlpha * deltaAlpha + deltaRed * deltaRed + deltaGreen * deltaGreen + deltaBlue * deltaBlue;

                    if (distance >= bestDistance)
                    {
                        continue;
                    }

                    bestDistance = distance;
                    bestMatch    = index;
                }

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

                palette.PixelIndex[index2] = bestMatch;
            }

            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);
        }
Пример #8
0
        private void button_ReadImage_Click(object sender, EventArgs e)
        {
            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;



                        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))
                            {
                                QuantizedPalette palette = quantizer.palette;
                                //quantized.Save(targetPath, ImageFormat.Png);


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

                                centerx   = bmDraw.Width / 2;
                                centery   = bmDraw.Height / 2;
                                newWidth  = Convert.ToInt32(inputimage.Width * scale / 2);
                                newHeight = Convert.ToInt32(inputimage.Height * scale / 2);
                                rg        = new Rectangle(centerx - newWidth, centery - newHeight, newWidth * 2, newHeight * 2);
                                //将bm内rg所指定的区域绘制到bm1
                                g.DrawImage(inputimage, rg);
                                this.pictureBox_Image.Image = bmDraw;
                            }
                        }
                    }
                    // }
                }
            }
        }
Пример #9
0
        protected override QuantizedPalette GetQuantizedPalette(int colorCount, ColorData data, IEnumerable<Box> cubes, int alphaThreshold)
        {
            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, int> cachedMaches = new Dictionary<int, int>();

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

                int bestMatch;
                int argb = pixel.Argb;

                if (!cachedMaches.TryGetValue(argb, out bestMatch))
                {
                    int match = quantizedPixels[pixelIndex];
                    bestMatch = 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;

                        int distance = deltaAlpha*deltaAlpha + deltaRed*deltaRed + deltaGreen*deltaGreen + deltaBlue*deltaBlue;

                        if (distance >= bestDistance)
                            continue;

                        bestDistance = distance;
                        bestMatch = lookupIndex;
                    }

                    cachedMaches[argb] = bestMatch;
                }

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

                palette.PixelIndex[pixelIndex] = bestMatch;
            }

            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;
        }
Пример #10
0
        private static QuantizedPalette GetQuantizedPalette(int colorCount, ColorData data, IEnumerable<Box> cubes)
        {
            var imageSize = data.Pixels.Count;
            var lookups = BuildLookups(cubes, data);

            for(var index = 0; index < imageSize; ++index)
            {
                var indexParts = BitConverter.GetBytes(data.QuantizedPixels[index]);
                data.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);
            var index2 = -1;

            foreach (var pixel in data.Pixels)
            {
                palette.PixelIndex[++index2] = -1;
                if(pixel.Alpha <= AlphaThreshold)
                    continue;

                var match = data.QuantizedPixels[index2];
                var bestMatch = match;
                var bestDistance = 100000000;
                var index = -1;

                foreach (var lookup in lookups.Lookups)
                {
                    ++index;
                    var deltaAlpha = pixel.Alpha - lookup.Alpha;
                    var deltaRed = pixel.Red - lookup.Red;
                    var deltaGreen = pixel.Green - lookup.Green;
                    var deltaBlue = pixel.Blue - lookup.Blue;

                    var distance = deltaAlpha * deltaAlpha + deltaRed * deltaRed + deltaGreen * deltaGreen + deltaBlue * deltaBlue;

                    if (distance >= bestDistance) continue;

                    bestDistance = distance;
                    bestMatch = index;
                }

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

                palette.PixelIndex[index2] = bestMatch;
            }

            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;
        }