本帖最后由 jinjazz 于 2012-05-03 10:30:34 编辑

解决方案 »

  1.   

    右键看我发的三张图的大小啊20k的png:http://img.my.csdn.net/uploads/201205/03/1336011498_9094.png
    7k的png:http://img.my.csdn.net/uploads/201205/03/1336011600_7018.png
    11k的gif:http://img.my.csdn.net/uploads/201205/03/1336011600_4627.gif这三张图内容都是一样的,只是质量和色彩有差别,因为图片颜色比较单一,所以这个损失可以接受
      

  2.   


    首先,JPG对于你这种只有文字和一些纯色的图像的压缩效果必然是比较差的,而这种图像的因为颜色比较单调,像PNG这种无损的压缩效果也是能较好的压缩效果的,这个图转换成GIF或者8位的PNG也不会出现色差,因为她总的颜色不超过256种, C#如果直接用Save保存 格式 PixelFormat24bppRGB 或PixelFormat32bppARGB 的图像为GIF,则他会先要帮你转换为8位的,这个转换时内部实现的,你无法控制,因此效果就不好。 如果你是win vista以上的系统,GDI1.1则提供了一个ConvertFormat函数,可以很好的控制不同色深之间的转换。然后再保存。
     http://msdn.microsoft.com/en-us/library/ms536306(v=vs.85).aspx http://social.msdn.microsoft.com/Forums/en-AU/vcgeneral/thread/260a977d-d6fd-4ccb-9ad7-6579da1c405b
      

  3.   

    http://freeimage.sourceforge.net/sourcecode.html
    using (FreeImageAPI.FreeImageBitmap fiBitmap = FreeImageAPI.FreeImageBitmap.FromHbitmap(bmp.GetHbitmap()))
                {
                    if (fiBitmap.ColorDepth > 24)
                    {
                        fiBitmap.ConvertColorDepth(FreeImageAPI.FREE_IMAGE_COLOR_DEPTH.FICD_08_BPP);
                    }                //quantize using the NeuQuant neural-net quantization algorithm 
                    fiBitmap.Quantize(FreeImageAPI.FREE_IMAGE_QUANTIZE.FIQ_NNQUANT, 256);
                    fiBitmap.Save("test_z.png", FreeImageAPI.FREE_IMAGE_FORMAT.FIF_PNG, FreeImageAPI.FREE_IMAGE_SAVE_FLAGS.PNG_Z_BEST_COMPRESSION);                //fiBitmap.Save(ms, FreeImageAPI.FREE_IMAGE_FORMAT.FIF_PNG, FreeImageAPI.FREE_IMAGE_SAVE_FLAGS.PNG_Z_DEFAULT_COMPRESSION);
                }
      

  4.   

    颜色数量少且有较多连续色块时最好用GIF,如果还嫌大,则可再根据用途进行压缩(比如:如果是用于ASP.NET,则可使用gzip压缩)
      

  5.   

    用LZMA算法吧,直接压缩索引过的bmp,试了下,可以小于1.4k
      

  6.   

    其实我很纳闷,纯色块上写文字,Div不是更好…
      

  7.   


    div没问题,已经完成了,img的布局逻辑等也已经实现,只是切片有些大。
      

  8.   

    lyserver(江南春)所贴的图像 只使用了3种颜色,大小为1705字节。于是我也想到了用PixelFormat4bppIndexed格式来保存为PNG图像,结果为2529字节,比lyserver的大,于是我去用右键属性去看lyserver发的PNG图像的位深,发现居然是2位的,那么也就意味着一个像素只用 2个位,四个像素才使用一个字节。这肯定比我PixelFormat4bppIndexed这个占用的空间小。可问题是:
    GDI或者GDI+有2位色深的图像,我记得只有1、4、8、16、24、32位的啊,连GDI+的位深常数里也没有PixelFormat2bppIndexed 这个枚举值啊,不知道哪位能解释下哦。
      

  9.   

    下面代码产生16色的PNG图像,大小为2.6K。
    色彩采样用了最简单的方法,既使用最先碰到的16色。如果要应对更多的输入(比如更多色彩),则可以采用其他采样算法,比如OctTree算法,比如clustering算法等等。void ToPNG4bit()
    {
        Bitmap source = new Bitmap("1336011498_9094.png");
        Bitmap target = new Bitmap(source.Width, source.Height, PixelFormat.Format4bppIndexed);    List<Color> paletteColors = new List<Color>();
        BitmapData bm = target.LockBits(new Rectangle(0, 0, target.Width, target.Height), ImageLockMode.ReadWrite, target.PixelFormat);
        for (int y = 0; y < source.Height; y++)
        {
            for (int x = 0; x < source.Width; x++)
            {
                Color color = source.GetPixel(x, y);
                int index = GetNearestMatch(paletteColors, color);
                
                byte b = Marshal.ReadByte(bm.Scan0, bm.Stride * y + x / 2);
                if ((x & 1) == 1)
                {
                    b = (byte)(index + (b & 0xF0));
                }
                else
                {
                    b = (byte)((index << 4) + (b & 0x0F));
                }
                Marshal.WriteByte(bm.Scan0, bm.Stride * y + x / 2, b);
            }
        }
        target.UnlockBits(bm);
        ColorPalette palette = target.Palette;
        paletteColors.CopyTo(palette.Entries);
        target.Palette = palette;    target.Save("B2-05.png", ImageFormat.Png); // 大小为2552bytes
    }private static int GetNearestMatch(List<Color> palette, Color color)
    {
        int index = 0;
        int minDiff = int.MaxValue;
        for (int i = 0; i < palette.Count; i++)
        {
            int diff =
                Math.Abs(palette[i].R - color.R) +
                Math.Abs(palette[i].G - color.G) +
                Math.Abs(palette[i].B - color.B);
            if( diff == 0)
            {
                return i;
            }
            if (diff < minDiff)
            {
                index = i;
                minDiff = diff;
            }
        }
        if (palette.Count < 16)
        {
            index = palette.Count;
            palette.Add(color);
        }
        return index;
    }
      

  10.   

    WPF提供了PngBitmapEncoder类用来存储PGN格式;提供了FormatConvertedBitmap类用来转化格式。
    因此,还可以这么做(如果是WinForm或Web,要添加WindowsBase和PresentationCore的引用):注意例子中调色板写定了4种颜色,这些颜色可以通过类似我在45楼提出的方法获得。void Test()
    {
        BitmapImage source = new BitmapImage();
        source.BeginInit();
        source.UriSource = new Uri("1336011498_9094.png");
        source.EndInit();    FormatConvertedBitmap target = new FormatConvertedBitmap();
        target.BeginInit();
        {
            target.Source = source;
            List<System.Windows.Media.Color> colors = new List<System.Windows.Media.Color>()
            {
                System.Windows.Media.Colors.Black,
                System.Windows.Media.Colors.Blue,
                System.Windows.Media.Color.FromRgb(255,208,208),
                System.Windows.Media.Colors.White,
            };
            BitmapPalette myPalette = new BitmapPalette(colors);
            target.DestinationPalette = myPalette;
            target.DestinationFormat = PixelFormats.Indexed2;
        }
        target.EndInit();    using (FileStream stream = File.OpenWrite("B2-05.png"))
        {
            PngBitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(target));
            encoder.Save(stream);
        }
    }
      

  11.   

    调用pngout.exe吧,可以直接通过粘贴板把图片传递过去
      

  12.   

    51 楼 更简单 不知道有没有 动态 获得 BitmapPalette 的方法
      

  13.   

    jpg的压缩一大堆的压缩算法,范式哈夫曼算法,行程压缩,还有狗屁的离散数学。
    自己研究了几个月也还没弄明白。JPG压缩解压缩的源码上传到我的资源了。
    http://download.csdn.net/detail/zanfeng/4274333
      

  14.   

    RGB/JPEG, DCT变换,Huffman编码
      

  15.   

    RGB/JPEG, DCT变换,Huffman编码
      

  16.   

    TO jinjazz:
    图片本身的大小有是极限的,我的那幅图片实际上3位色调色板索引(丢失了白色),如果还想小,则看你的实际应用了。如果图片解码是由自己实现的,则可以在图片有损压缩的基础上,再使用文件压缩技术(比如这种连续色较多的图片,使用最基本的行程压缩或WMF回放效果应该不错),如果是用于浏览器则可以考虑我前面提到的GZIP压缩。
      

  17.   

    TO jinjazz:
    图片本身的大小有是极限的,我的那幅图片实际上3位色调色板索引(丢失了白色),如果还想小,则看你的实际应用了。如果图片解码是由自己实现的,则可以在图片有损压缩的基础上,再使用文件压缩技术(比如这种连续色较多的图片,使用最基本的行程压缩或WMF回放效果应该不错),如果是用于浏览器则可以考虑我前面提到的GZIP压缩。
      

  18.   

    楼上比小的,貌似都拼命压缩颜色数,结果丢颜色了,把白的给丢了。用ImageMagick吧,哪里都通用的convert xxx.png -strip -colors N -define png:compression-level=9 yyy.png有.net接口
      

  19.   

    上面就几个3个颜色, 和一组文字
    直接写代码动态生成bmp最小
      

  20.   

    /**
     * GZIP压缩
     * */
    public static byte[] compress(String str) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try {
    GZIPOutputStream gOutputStream = new GZIPOutputStream(out);
    gOutputStream.write(str.getBytes("UTF-8"));
    gOutputStream.finish();
    gOutputStream.close();
    out.flush();
    out.close();
    }
    catch (IOException e) {
    e.printStackTrace();
    }
    return out.toByteArray(); }