求图像压缩算法
--------------------编程问答-------------------- 请大家帮忙 --------------------编程问答-------------------- 所占空间大小比原图小2-3倍? --------------------编程问答-------------------- 右键看我发的三张图的大小啊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
这三张图内容都是一样的,只是质量和色彩有差别,因为图片颜色比较单一,所以这个损失可以接受 --------------------编程问答--------------------
首先,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
--------------------编程问答-------------------- 你这个
1)调色板
2)emf
--------------------编程问答-------------------- --------------------编程问答-------------------- 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);
} --------------------编程问答-------------------- --------------------编程问答-------------------- 有意思,学习 --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- 有意思,学习 --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- 颜色数量少且有较多连续色块时最好用GIF,如果还嫌大,则可再根据用途进行压缩(比如:如果是用于ASP.NET,则可使用gzip压缩) --------------------编程问答-------------------- 4KB+- --------------------编程问答-------------------- --------------------编程问答-------------------- png是相對很小的 --------------------编程问答-------------------- 6.8K太大了。2K的飘过。。。
--------------------编程问答-------------------- 用LZMA算法吧,直接压缩索引过的bmp,试了下,可以小于1.4k --------------------编程问答-------------------- 看完后,我只有一个感觉,房价太贵了! --------------------编程问答-------------------- 18楼,21楼多谢
请教21楼兄弟c#可以直接处理吗 --------------------编程问答-------------------- 呼唤牛人出现!!!!!!!秒杀剪子!!!
2K那个,,你咋弄的呢 --------------------编程问答-------------------- 我也不懂 --------------------编程问答-------------------- 不明白 --------------------编程问答-------------------- 来个1.6k的,
--------------------编程问答-------------------- 地址错了。
--------------------编程问答--------------------
这个如何实现?色彩不能改,表格不止1种颜色,但也不会超过3种
--------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- 其实我很纳闷,纯色块上写文字,Div不是更好… --------------------编程问答--------------------
div没问题,已经完成了,img的布局逻辑等也已经实现,只是切片有些大。 --------------------编程问答-------------------- --------------------编程问答-------------------- 我靠,哪儿的房子啊。这么贵 --------------------编程问答--------------------
数据是假的,不过京沪2w貌似也买不到城里面 --------------------编程问答-------------------- --------------------编程问答-------------------- 六环外,鉴定完毕。。。 --------------------编程问答-------------------- --------------------编程问答--------------------
顶! --------------------编程问答-------------------- 比较新鲜 --------------------编程问答-------------------- 进来膜拜大神。楼主找到解决方法后不要忘了贴最佳方案。 --------------------编程问答-------------------- lyserver(江南春)所贴的图像 只使用了3种颜色,大小为1705字节。于是我也想到了用PixelFormat4bppIndexed格式来保存为PNG图像,结果为2529字节,比lyserver的大,于是我去用右键属性去看lyserver发的PNG图像的位深,发现居然是2位的,那么也就意味着一个像素只用 2个位,四个像素才使用一个字节。这肯定比我PixelFormat4bppIndexed这个占用的空间小。可问题是:
GDI或者GDI+有2位色深的图像,我记得只有1、4、8、16、24、32位的啊,连GDI+的位深常数里也没有PixelFormat2bppIndexed 这个枚举值啊,不知道哪位能解释下哦。 --------------------编程问答-------------------- 下面代码产生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;
}
这个简单,回头试一下
--------------------编程问答--------------------
2位 存的不实色彩值 是指向 色彩在 自己色彩板 上的编号
两位就是 4个,色彩板最多四个颜色,这四个颜色 可以 有各种色深 24、32
--------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- WPF提供了PngBitmapEncoder类用来存储PGN格式;提供了FormatConvertedBitmap类用来转化格式。
因此,还可以这么做(如果是WinForm或Web,要添加WindowsBase和PresentationCore的引用):
注意例子中调色板写定了4种颜色,这些颜色可以通过类似我在45楼提出的方法获得。
--------------------编程问答-------------------- 29L的降低画质了吧- - 这样那还可以再小点 1.3k
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);
}
}
--------------------编程问答-------------------- 调用pngout.exe吧,可以直接通过粘贴板把图片传递过去 --------------------编程问答-------------------- 51 楼 更简单 不知道有没有 动态 获得 BitmapPalette 的方法
--------------------编程问答-------------------- jpg的压缩一大堆的压缩算法,范式哈夫曼算法,行程压缩,还有狗屁的离散数学。
自己研究了几个月也还没弄明白。
JPG压缩解压缩的源码上传到我的资源了。
http://download.csdn.net/detail/zanfeng/4274333 --------------------编程问答--------------------
嗯不要分,收下了,多谢了
--------------------编程问答--------------------
下载了,居然不要分,我看看,有什么心得也共享下。
--------------------编程问答-------------------- 混经验的,学习图片压缩的算法。 --------------------编程问答--------------------
你的头像看着我真晕 --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- RGB/JPEG, DCT变换,Huffman编码 --------------------编程问答-------------------- RGB/JPEG, DCT变换,Huffman编码 --------------------编程问答-------------------- 你这也叫图像压缩?不就图片格式转换了一下而以,兄弟别吓唬人 --------------------编程问答-------------------- --------------------编程问答-------------------- TO jinjazz:
图片本身的大小有是极限的,我的那幅图片实际上3位色调色板索引(丢失了白色),如果还想小,则看你的实际应用了。如果图片解码是由自己实现的,则可以在图片有损压缩的基础上,再使用文件压缩技术(比如这种连续色较多的图片,使用最基本的行程压缩或WMF回放效果应该不错),如果是用于浏览器则可以考虑我前面提到的GZIP压缩。 --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答--------------------
都是高手,向你们学习 --------------------编程问答--------------------
多谢,这贴让我长进了 --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- 图做的再小也掩盖不了天价的房子 --------------------编程问答-------------------- --------------------编程问答-------------------- TO jinjazz:
图片本身的大小有是极限的,我的那幅图片实际上3位色调色板索引(丢失了白色),如果还想小,则看你的实际应用了。如果图片解码是由自己实现的,则可以在图片有损压缩的基础上,再使用文件压缩技术(比如这种连续色较多的图片,使用最基本的行程压缩或WMF回放效果应该不错),如果是用于浏览器则可以考虑我前面提到的GZIP压缩。 --------------------编程问答-------------------- --------------------编程问答-------------------- 房子打个0.1折,我可以借钱首付!! --------------------编程问答-------------------- --------------------编程问答-------------------- 学习下其他人怎么做的 --------------------编程问答-------------------- --------------------编程问答-------------------- 楼上比小的,貌似都拼命压缩颜色数,结果丢颜色了,把白的给丢了。
用ImageMagick吧,哪里都通用的
convert xxx.png -strip -colors N -define png:compression-level=9 yyy.png
有.net接口 --------------------编程问答-------------------- --------------------编程问答-------------------- 上面就几个3个颜色, 和一组文字
直接写代码动态生成bmp最小。。。
--------------------编程问答-------------------- --------------------编程问答-------------------- 不知道和H264有没有关系 --------------------编程问答--------------------
呵呵,很多人都有这个感觉吧 --------------------编程问答-------------------- --------------------编程问答-------------------- 做广告的吧? --------------------编程问答-------------------- 房价太贵伤不起啊! --------------------编程问答-------------------- 哈哈 如果房价能代码压缩下就好了 --------------------编程问答-------------------- --------------------编程问答-------------------- /**
* 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();
} --------------------编程问答-------------------- LZ可以考虑GIF的特点 --------------------编程问答-------------------- --------------------编程问答-------------------- 这相当于上海中环的房价呀 --------------------编程问答-------------------- 这个知识很不错哈 --------------------编程问答-------------------- 不错不错
--------------------编程问答-------------------- 都是神呐
补充:.NET技术 , C#