求助,关于图片缩小后失真的问题
是这样的,小弟现在做的项目,在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++) { //取周围9点的值。位于边缘上的点不做改变。 if (x == 0 || x == w - 1 || y == 0 || y == h - 1) { //不做 pOut[0] = pIn[0]; pOut[1] = pIn[1]; pOut[2] = pIn[2]; } else { int r1, r2, r3, r4, r5, r6, r7, r8, r0; int g1, g2, g3, g4, g5, g6, g7, g8, g0; int b1, b2, b3, b4, b5, b6, b7, b8, b0; float vR, vG, vB; //左上 p = pIn - stride - 3; r1 = p[2]; g1 = p[1]; b1 = p[0]; //正上 p = pIn - stride; r2 = p[2]; g2 = p[1]; b2 = p[0]; //右上 p = pIn - stride + 3; r3 = p[2]; g3 = p[1]; b3 = p[0]; //左侧 p = pIn - 3; r4 = p[2]; g4 = p[1]; b4 = p[0]; //右侧 p = pIn + 3; r5 = p[2]; g5 = p[1]; b5 = p[0]; //右下 p = pIn + stride - 3; r6 = p[2]; g6 = p[1]; b6 = p[0]; //正下 p = pIn + stride; r7 = p[2]; g7 = p[1]; b7 = p[0]; //右下 p = pIn + stride + 3; r8 = p[2]; g8 = p[1]; b8 = p[0]; //自己 p = pIn; r0 = p[2]; g0 = p[1]; b0 = p[0]; vR = (float)r0 - (float)(r1 + r2 + r3 + r4 + r5 + r6 + r7 + r8) / 8; vG = (float)g0 - (float)(g1 + g2 + g3 + g4 + g5 + g6 + g7 + g8) / 8; vB = (float)b0 - (float)(b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8) / 8; vR = r0 + vR * val; vG = g0 + vG * val; vB = b0 + vB * val; if (vR > 0) { vR = Math.Min(255, vR); } else { vR = Math.Max(0, vR); } if (vG > 0) { vG = Math.Min(255, vG); } else { vG = Math.Max(0, vG); } if (vB > 0) { vB = Math.Min(255, vB); } else { vB = Math.Max(0, vB); } pOut[0] = (byte)vB; pOut[1] = (byte)vG; pOut[2] = (byte)vR; } pIn += 3; pOut += 3; }// end of x pIn += srcData.Stride - w * 3; pOut += srcData.Stride - w * 3; } // end of y } b.UnlockBits(srcData); bmpRtn.UnlockBits(dstData); return bmpRtn; } catch { return null; } } // end of KiSharpen