日期:2014-05-18  浏览次数:21046 次

求助,关于图片缩小后失真的问题
是这样的,小弟现在做的项目,在ipad上生成了尺寸为“600*456”,20KB 的PNG格式图片(客户的签名),现在要把这个图片缩放到网页中一个100*15的框内。
图片的处理可以采用两种方法:

一、是在C#中提前转换图片尺寸。
之前有尝试过在C#中用bitmap按原图缩放创建一个100*15的PNG图片,但效果很差。
通过C#把PNG格式的图片缩小,谁能提供一个比较好的方法能让他在缩小30倍的情况下还能保持原来的样子?还是说这张图是位图,缩太小必然失真?那通过转换成矢量图可不可以解决?C#的话有什么好办法实现根据以后图片生成矢量图的吗?

二、原图插入HTML后再做处理。
图片直接插入后也是失真,主要表现在有的线断断续续,变成一个个断点了,而且变的很淡,我想请问下为什么会出现这种情况?HTML对这类问题有什么解决方法?

小弟本来就菜,.NET更是新手一个,对方催得紧,实在没辙,只能上来求助论坛的各位大侠了。
其实,我最好奇为什么在word和excel中插入图片,不管你怎么折腾,缩的再小都还是可以显示的很好,而我放到HTML中就不行了,有人能告知下是怎么实现的吗?是否可以利用?

问题界限定位有点模糊了,也不知道究竟是通过HTML解决还是要通过C#,不管了,有哪位大神有解决之道吗?小菜跪求了。

------解决方案--------------------
C# code
        public static Image GenThumbnail(Image imageFrom, int width, int height, int quality)
        {
            // 源图宽度及高度 
            int imageFromWidth = imageFrom.Width;
            int imageFromHeight = imageFrom.Height;

            // 生成的缩略图实际宽度及高度 
            if (width >= imageFromWidth && height >= imageFromHeight)
            {
                return imageFrom;
            }
            else
            {
                // 生成的缩略图在上述"画布"上的位置 
                int X = 0;
                int Y = 0;

                decimal wpercent = (decimal)width / imageFromWidth;
                decimal hpercent = (decimal)height / imageFromHeight;
                if (wpercent > hpercent)
                {
                    width = (int)(imageFromWidth * hpercent);
                }
                else if (wpercent < hpercent)
                {
                    height = (int)(imageFromHeight * wpercent);
                }

                // 创建画布 
                Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
                bmp.SetResolution(imageFrom.HorizontalResolution, imageFrom.VerticalResolution);
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    // 用白色清空 
                    g.Clear(Color.White);

                    // 指定高质量的双三次插值法。执行预筛选以确保高质量的收缩。此模式可产生质量最高的转换图像。 
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;

                    // 指定高质量、低速度呈现。 
                    g.SmoothingMode = SmoothingMode.HighQuality;

                    // 在指定位置并且按指定大小绘制指定的 Image 的指定部分。 
                    g.DrawImage(imageFrom, new Rectangle(X, Y, width, height), new Rectangle(0, 0, imageFromWidth, imageFromHeight), GraphicsUnit.Pixel);

                    return bmp;
                }
            }
        }

------解决方案--------------------
试试锐化方案:
C# code

        /// <summary>
        /// 锐化
        /// </summary>
        /// <param name="b">原始Bitmap</param>
        /// <param name="val">锐化程度。取值[0,1]。值越大锐化程度越高</param>
        /// <returns>锐化后的图像</returns>
        public static Bitmap KiSharpen(Bitmap b, float val)
        {
            if (b == null)
            {
                return null;
            }

            int w = b.Width;
            int h = b.Height;

            try
            {

                Bitmap bmpRtn = new Bitmap(w, h, PixelFormat.Format24bppRgb);

                BitmapData srcData = b.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                BitmapData dstData = bmpRtn.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

                unsafe
                {
                    byte* pIn = (byte*)srcData.Scan0.ToPointer();
                    byte* pOut = (byte*)dstData.Scan0.ToPointer();
                    int stride = srcData.Stride;
                    byte* p;

                    for (int y = 0; y < h; y++)
                    {
                        for (int x = 0; x < w; x++)
                        {