解决方案 »
- ext+asp.net 中怎么能获得当前列的显示状态
- !<帮忙推荐几本 .NET 网络编程的书籍>!
- 请问各位,我该如何在子类中重写父类的属性呢?以下是我的代码,重写了控件的Text属性,但却不能在属性窗中显示
- 请教高手:从dataTable 导出数据生成dbf文件时,如何自动设定dbf各列的长度及类型
- 很弱的问题,.net2005中的下拉列表的问题
- 使用MessageBox.show()时出现问题
- 在WinForm中怎样把MDI父窗体的子窗体的子窗体设为父窗体的子窗体
- 请问C#如何获取Word文档中图片的坐标,谢谢了。
- 打开水晶报表时显示“未将对象引用设置到对象的实例”,只有10分,全部送出
- WebForm 中如何在DataGrid中选中一行,并获得此纪录?谢谢!
- bat 批处理文件有空格
- C#程序运行不了
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
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);
}
div没问题,已经完成了,img的布局逻辑等也已经实现,只是切片有些大。
GDI或者GDI+有2位色深的图像,我记得只有1、4、8、16、24、32位的啊,连GDI+的位深常数里也没有PixelFormat2bppIndexed 这个枚举值啊,不知道哪位能解释下哦。
色彩采样用了最简单的方法,既使用最先碰到的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;
}
因此,还可以这么做(如果是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);
}
}
自己研究了几个月也还没弄明白。JPG压缩解压缩的源码上传到我的资源了。
http://download.csdn.net/detail/zanfeng/4274333
图片本身的大小有是极限的,我的那幅图片实际上3位色调色板索引(丢失了白色),如果还想小,则看你的实际应用了。如果图片解码是由自己实现的,则可以在图片有损压缩的基础上,再使用文件压缩技术(比如这种连续色较多的图片,使用最基本的行程压缩或WMF回放效果应该不错),如果是用于浏览器则可以考虑我前面提到的GZIP压缩。
图片本身的大小有是极限的,我的那幅图片实际上3位色调色板索引(丢失了白色),如果还想小,则看你的实际应用了。如果图片解码是由自己实现的,则可以在图片有损压缩的基础上,再使用文件压缩技术(比如这种连续色较多的图片,使用最基本的行程压缩或WMF回放效果应该不错),如果是用于浏览器则可以考虑我前面提到的GZIP压缩。
直接写代码动态生成bmp最小
* 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(); }