图片压缩转base64
第一种
1 /// <summary> 2 /// 高质量压缩图片 3 /// </summary> 4 /// <param name="flag">压缩质量(数字越小压缩率越高) 1-100</param> 5 /// <param name="filePath">图片地址</param> 6 /// <returns></returns> 7 private string CompressedPicture(int flag, string filePath) 8 { 9 var imageByte = File.ReadAllBytes(filePath); 10 Stream msSource = new MemoryStream(imageByte); 11 var list = new List<StreamContent>(); 12 var aa = new StreamContent(msSource); 13 var image = Image.FromStream(msSource); 14 ImageFormat tFormat = image.RawFormat; 15 int dHeight = image.Width < 1024 ? image.Height : image.Height / 2;//图片质量低不压缩 16 int dWidth = image.Width < 1024 ? image.Width : image.Width / 2;//图片质量低不压缩 17 var cWidth = 0; 18 var cHeigth = 0; 19 20 #region 按比例缩放 21 22 if (image.Height> dHeight || image.Width > dWidth) 23 { 24 if ((image.Width * dHeight) > (image.Width * dWidth)) 25 { 26 cWidth = dWidth; 27 cHeigth = (dWidth * image.Height) / (image.Width); 28 } 29 else 30 { 31 cHeigth = dHeight; 32 cWidth = (image.Width * dHeight) / (image.Height); 33 } 34 } 35 else 36 { 37 cWidth = image.Width; 38 cHeigth = image.Height; 39 } 40 var ob = new Bitmap(dWidth, dHeight); 41 var g = Graphics.FromImage(ob); 42 //清除画布并使用指定的背景颜色对其进行绘制 43 g.Clear(Color.WhiteSmoke); 44 //设置合成质量(此处高质量) 45 g.CompositingQuality = CompositingQuality.HighQuality; 46 //设置平滑模式(指定直线、 曲线和已填充区域的边缘是否使用平滑处理。也称为抗锯齿) 47 g.SmoothingMode = SmoothingMode.HighQuality; 48 // 49 g.InterpolationMode = InterpolationMode.HighQualityBicubic; 50 g.DrawImage(image, new Rectangle((dWidth - cWidth) / 2, (dHeight - cHeigth) / 2, cWidth, cHeigth), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel); 51 g.Dispose(); 52 #endregion 53 54 #region 保存图片 设置压缩质量 55 56 var ep = new EncoderParameters(); 57 var qy = new long[1]; 58 qy[0] = flag; 59 var eParam = new EncoderParameter(Encoder.Quality, qy); 60 ep.Param[0] = eParam; 61 try 62 { 63 var arrayICI = ImageCodecInfo.GetImageEncoders(); 64 ImageCodecInfo jpegICIinfo = null; 65 for (var i = 0; i < arrayICI.Length; i++) 66 { 67 if (arrayICI[i].FormatDescription.Equals("JPEG")) 68 { 69 jpegICIinfo = arrayICI[i]; 70 break; 71 } 72 } 73 MemoryStream msSaveImage = new MemoryStream(); 74 if (jpegICIinfo != null) 75 { 76 ob.Save(msSaveImage, jpegICIinfo, ep);//高质量保存 77 } 78 else 79 { 80 ob.Save(msSaveImage, tFormat); 81 } 82 byte[] imageBytes = msSaveImage.ToArray(); 83 msSaveImage.Close(); 84 //return "data:image/jpeg;base64,"+ Convert.ToBase64String(imageBytes); 85 var str = Convert.ToBase64String(imageBytes); 86 return str; 87 } 88 catch 89 { 90 return ""; 91 } 92 finally 93 { 94 //释放资源 95 image.Dispose(); 96 ob.Dispose(); 97 } 98 #endregion 99 }
第二种:
1 /// <summary> 2 /// 压缩图片并且转base64 3 /// </summary> 4 /// <param name="width"></param> 5 /// <param name="height"></param> 6 /// <param name="filePath">图片地址</param> 7 /// <returns></returns> 8 public static byte[] CutImage(int width, int height, string filePath) 9 { 10 var aa = File.ReadAllBytes(filePath); 11 MemoryStream msSource = new MemoryStream(aa); 12 Bitmap btImage = new Bitmap(msSource); 13 msSource.Close(); 14 Image serverImage = btImage; 15 //画板大小 16 int finalWidth = width, finalHeight = height; 17 int srcImageWidth = serverImage.Width; 18 int srcImageHeight = serverImage.Height; 19 if (srcImageWidth > srcImageHeight) 20 { 21 finalHeight = srcImageHeight * width / srcImageWidth; 22 } 23 else 24 { 25 finalWidth = srcImageWidth * height / srcImageHeight; 26 } 27 //新建一个bmp图片 28 Image newImage = new Bitmap(width, height); 29 //新建一个画板 30 Graphics g = Graphics.FromImage(newImage); 31 //设置高质量插值法 32 g.InterpolationMode = InterpolationMode.High; 33 //设置高质量,低速度呈现平滑程度 34 g.SmoothingMode = SmoothingMode.HighQuality; 35 //清空画布并以透明背景色填充 36 g.Clear(Color.White); 37 //在指定位置并且按指定大小绘制原图片的指定部分 38 g.DrawImage(serverImage, new Rectangle((width - finalWidth) / 2, (height - finalHeight) / 2, finalWidth, finalHeight), 0, 0, srcImageWidth, srcImageHeight, GraphicsUnit.Pixel); 39 //以jpg格式保存缩略图 40 MemoryStream msSaveImage = new MemoryStream(); 41 newImage.Save(msSaveImage, ImageFormat.Jpeg); 42 serverImage.Dispose(); 43 newImage.Dispose(); 44 g.Dispose(); 45 byte[] imageBytes = msSaveImage.ToArray(); 46 msSaveImage.Close(); 47 //return "data:image/jpeg;base64," + Convert.ToBase64String(imageBytes); 48 49 50 ////base64压缩方式一 51 //MemoryStream ms = new MemoryStream(); 52 //byte[] compressedData = (byte[])msSaveImage.ToArray(); 53 //GZipStream compressedzipStream = new GZipStream(ms, CompressionMode.Compress, true); 54 //compressedzipStream.Write(imageBytes, 0, imageBytes.Length); 55 //compressedzipStream.Close(); 56 //var data= ms.ToArray(); 57 //return "data:image/jpeg;base64," + Convert.ToBase64String(data, 0, data.Length); 58 59 ////base64压缩方式二 60 //MemoryStream ms = new MemoryStream(); 61 //Stream s = new BZip2OutputStream(ms); 62 //s.Write(imageBytes, 0, imageBytes.Length); 63 //s.Close(); 64 //byte[] compressedData = (byte[])ms.ToArray(); 65 //return "data:image/jpeg;base64," + Convert.ToBase64String(compressedData, 0, compressedData.Length); 66 //return Convert.ToBase64String(imageBytes); 67 //return Compress2(Convert.ToBase64String(imageBytes)); 68 return Compress2(imageBytes); 69 } 70 public static byte[] Compress2(byte[] rawData) 71 { 72 //byte[] rawData = System.Text.Encoding.UTF8.GetBytes(rawString.ToString()); 73 MemoryStream ms = new MemoryStream(); 74 GZipStream compressedzipStream = new GZipStream(ms, CompressionMode.Compress, true); 75 compressedzipStream.Write(rawData, 0, rawData.Length); 76 compressedzipStream.Close(); 77 byte[] zippedData = ms.ToArray(); 78 return zippedData; 79 }
高质量压缩到指定大小范围不发生旋转
图片压缩前进行旋转,压缩后的图片就不会发生旋转
1 /// <summary> 2 /// 高质量压缩图片 3 /// </summary> 4 /// <param name="image">image</param> 5 /// <param name="flag">压缩质量(数字越小压缩率越高) 1-100</param> 6 /// <param name="fileDire">缩略图路径</param> 7 /// <param name="fileName">缩略图名称(包含后缀)</param> 8 /// <param name="size">指定压缩大小</param> 9 /// <param name="lastSize">最后一次压缩大小,用于判定是否可再次压缩至最小</param> 10 /// <returns>返回新生成的图完整路径</returns> 11 private static string CompressedPicture(Image image, int flag, string fileDire, string fileName, int size = 0, int lastSize = 0) 12 { 13 ImageFormat tFormat = image.RawFormat; 14 //旋转图片,保证图片在压缩后旋转会正常的角度 15 RotateImage(image); 16 int dHeight = image.Height < 420 ? image.Height : 420;//图片质量低不压缩 17 int dWidth = image.Width < 310 ? image.Width : 310;//图片质量低不压缩 18 var cWidth = 0; 19 var cHeigth = 0; 20 var fullUrl = fileDire + fileName; 21 if (!Directory.Exists(fileDire)) 22 { 23 Directory.CreateDirectory(fileDire); 24 } 25 #region 按比例缩放 26 if (image.Height > dHeight || image.Width > dWidth) 27 { 28 if ((image.Width * dHeight) > (image.Height * dWidth)) 29 { 30 cWidth = dWidth; 31 cHeigth = (image.Height*dWidth)/(image.Width);//按宽度缩放比例缩放高度 32 } 33 else 34 { 35 cHeigth = dHeight; 36 cWidth = (image.Width * dHeight) / (image.Height);//按高度缩放比例缩放宽度 37 } 38 } 39 else 40 { 41 cWidth = image.Width; 42 cHeigth = image.Height; 43 } 44 45 var ob = new Bitmap(cWidth, cHeigth); 46 var g = Graphics.FromImage(ob); 47 //清除画布并使用指定的背景颜色对其进行绘制 48 g.Clear(Color.WhiteSmoke); 49 //设置合成质量(此处高质量) 50 g.CompositingQuality = CompositingQuality.HighQuality; 51 //设置平滑模式(指定直线、 曲线和已填充区域的边缘是否使用平滑处理。也称为抗锯齿) 52 g.SmoothingMode = SmoothingMode.HighQuality; 53 // 54 g.InterpolationMode = InterpolationMode.HighQualityBicubic; 55 //第一个System.Drawing.Rectangle是原图片写在画布上的坐标和宽高,第二个是原图片的画布坐标和宽高,最后一个参数是指定数值单位为像素 56 g.DrawImage(image, new Rectangle(0, 0, cWidth, cHeigth), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel); 57 g.Dispose(); 58 #endregion 59 60 #region 保存图片 设置压缩质量 61 62 var ep = new EncoderParameters(); 63 var qy = new long[1]; 64 qy[0] = flag; 65 var eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy); 66 ep.Param[0] = eParam; 67 try 68 { 69 //找到系统中可用的图片编码器信息 70 var arrayICI = ImageCodecInfo.GetImageEncoders(); 71 ImageCodecInfo jpegICIinfo = null; 72 for (var i = 0; i < arrayICI.Length; i++) 73 { 74 if (arrayICI[i].FormatDescription.Equals("JPEG")) 75 { 76 jpegICIinfo = arrayICI[i]; 77 break; 78 } 79 } 80 //如果编码器存在的,可以压缩 81 if (jpegICIinfo != null) 82 { 83 ob.Save(fullUrl, jpegICIinfo, ep); 84 if (size != 0) 85 { 86 //FileInfo fi = new FileInfo(fullUrl); 87 byte[] bytes = File.ReadAllBytes(fullUrl); 88 if (bytes.Length > 1024 * size) 89 { 90 //防止死循环 91 if (lastSize != bytes.Length) 92 { 93 lastSize = bytes.Length; 94 flag = flag - 10 <= 0 ? 1 : flag - 10; 95 CompressedPicture(image, flag, fileDire, fileName, size, lastSize); 96 } 97 } 98 } 99 100 } 101 else 102 { 103 ob.Save(fullUrl, tFormat); 104 } 105 106 return fullUrl; 107 } 108 catch 109 { 110 return ""; 111 } 112 finally 113 { 114 //释放资源 115 image.Dispose(); 116 ob.Dispose(); 117 } 118 #endregion 119 }
图片旋转
1 /// <summary> 2 /// 旋转图片 3 /// </summary> 4 /// <param name="img"></param> 5 private static void RotateImage(Image img) 6 { 7 var exif = ReadExif(img); 8 if (exif.ContainsKey("Orientation")) 9 { 10 switch (int.Parse(exif["Orientation"])) 11 { 12 case 2: 13 img.RotateFlip(RotateFlipType.RotateNoneFlipX);//horizontal flip 14 break; 15 case 3: 16 img.RotateFlip(RotateFlipType.Rotate180FlipNone);//right-top 17 //img = Rotate((Bitmap)img, 180); 18 break; 19 case 4: 20 img.RotateFlip(RotateFlipType.RotateNoneFlipY);//vertical flip 21 break; 22 case 5: 23 img.RotateFlip(RotateFlipType.Rotate90FlipX); 24 break; 25 case 6: 26 img.RotateFlip(RotateFlipType.Rotate90FlipNone);//right-top 27 break; 28 case 7: 29 img.RotateFlip(RotateFlipType.Rotate270FlipX); 30 break; 31 case 8: 32 img.RotateFlip(RotateFlipType.Rotate270FlipNone);//left-bottom 33 break; 34 } 35 } 36 } 37 38 /// <summary> 39 /// 获取图片旋转角度 40 /// </summary> 41 /// <param name="image"></param> 42 /// <returns></returns> 43 private static Dictionary<string, string> ReadExif(Image image) 44 { 45 var exif = new Dictionary<string, string>(); 46 var properties = image.PropertyItems; 47 foreach (var property in properties) 48 { 49 switch (property.Id) 50 { 51 case 0x010E: 52 exif["ImageTitle"] = ASCIIToString(property.Value); 53 break; 54 case 0x010F: 55 exif["Make"] = ASCIIToString(property.Value); 56 break; 57 case 0x0110: 58 exif["Model"] = ASCIIToString(property.Value); 59 break; 60 case 0x0112: 61 exif["Orientation"] = ShortToString(property.Value, 0); 62 break; 63 case 0x011A: 64 exif["XResolution"] = RationalToSingle(property.Value, 0); 65 break; 66 case 0x011B: 67 exif["YResolution"] = RationalToSingle(property.Value, 0); 68 break; 69 case 0x0128: 70 exif["ResolutionUnit"] = ShortToString(property.Value, 0); 71 break; 72 case 0x0131: 73 exif["Software"] = ASCIIToString(property.Value); 74 break; 75 case 0x0132: 76 exif["DateTime"] = ASCIIToString(property.Value); 77 break; 78 //GPS 79 case 0x0002: 80 exif["GPSLatitude"] = string.Format("{0}°{1}′{2}″", 81 RationalToSingle(property.Value, 0), 82 RationalToSingle(property.Value, 8), 83 RationalToSingle(property.Value, 16) 84 ); 85 break; 86 case 0x0004: 87 exif["GPSLongitude"] = string.Format("{0}°{1}′{2}″", 88 RationalToSingle(property.Value, 0), 89 RationalToSingle(property.Value, 8), 90 RationalToSingle(property.Value, 16) 91 ); 92 break; 93 case 0x0006: 94 exif["GPSAltitude"] = RationalToSingle(property.Value, 0); 95 break; 96 } 97 } 98 return exif; 99 } 100 private static string ByteToString(byte[] b, int startindex) 101 { 102 if (startindex + 1 <= b.Length) 103 return ((char)b[startindex]).ToString(); 104 else 105 return string.Empty; 106 } 107 108 private static string ShortToString(byte[] b, int startindex) 109 { 110 if (startindex + 2 <= b.Length) 111 return BitConverter.ToInt16(b, startindex).ToString(); 112 else 113 return string.Empty; 114 } 115 116 private static string RationalToSingle(byte[] b, int startindex) 117 { 118 if (startindex + 8 <= b.Length) 119 return (BitConverter.ToSingle(b, startindex) / BitConverter.ToSingle(b, startindex + 4)).ToString(); 120 else 121 return string.Empty; 122 } 123 124 private static string ASCIIToString(byte[] b) 125 { 126 return Encoding.ASCII.GetString(b); 127 }