using System; using System.Collections.Generic; using System.Text; using System.Data; using System.IO; using System.Drawing; namespace DAL { public class ImgUtil { /// <summary> /// byte[]数组转换Bitmap /// </summary> /// <param name="buffer">byte[]数组</param> /// <returns>Bitmap</returns> private static Bitmap Bytes2Bitmap(byte[] buffer) { using (MemoryStream ms = new MemoryStream()) { ms.Write(buffer, 0, buffer.Length); Bitmap bmp = new Bitmap(ms); return bmp; } } /// <summary> /// Bitmap转换成byte[]数组 /// </summary> /// <param name="bmp">Bitmap</param> /// <returns>byte[]数组</returns> private static byte[] Bitmap2Bytes(Bitmap bmp) { Bitmap xbmp = new Bitmap(bmp); using (MemoryStream ms = new MemoryStream()) { xbmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); ms.Flush(); byte[] buffer = ms.GetBuffer(); return buffer; } } /// <summary> /// 根据图片路径得到位图 /// </summary> /// <param name="imgPath">图片路径</param> /// <returns>位图</returns> private static Bitmap GetBitmap(string imgPath) { using (FileStream fs = new FileStream(imgPath, FileMode.Open, FileAccess.Read)) { Bitmap bmp = new Bitmap(fs); return bmp; } } /// <summary> /// 将位图转换为byte[]数组,如果大于100K则进行压缩,使其大小小于等于100K /// </summary> /// <param name="bmp">位图</param> /// <returns>byte[]数组</returns> private static byte[] CompressImage(Bitmap bmp) { byte[] buffer = null; int ImageMaxSize = 100 * 1024;//限制图片大小为100K Bitmap xbmp = new Bitmap(bmp); MemoryStream ms = new MemoryStream(); try { xbmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); ms.Flush(); /* * 算法一:通过固定长宽的乘积直接得到图像大小,缺点是图像压缩可能过小 * */ //if (ms.Length > ImageMaxSize) //{ // Image m_src_image = Image.FromStream(ms); // //new_height*new_width = 100*1024 // //m_src_image.Height / m_src_image.Width = new_height / new_width // double new_height = Math.Sqrt(ImageMaxSize * m_src_image.Height / m_src_image.Width); // double new_width = Math.Sqrt(ImageMaxSize * m_src_image.Width / m_src_image.Height); // ms = CompressImageMemoryStream(ms, new_height, new_width); //} /* * 算法二:取近似值的办法,使图像大小趋近于100K,缺点是影响速度,如果图片量大的话,需要进行修改 * */ if (ms.Length > ImageMaxSize) { double new_height = 0; double new_width = 0; double min = 0, max = 1, middle; for (int i = 0; i < 10; i++) { middle = (min + max) / 2; Image m_src_image = Image.FromStream(ms); double middle_height = middle * m_src_image.Height; double middle_width = middle * m_src_image.Width; MemoryStream newMS = CompressImageMemoryStream(ms, middle_height, middle_width); //容量比长度值要大,压缩后存贮的大小等于容量的大小而不是长度值 //存储时,图片大小是以容量的65536倍数进行计算,即64K,128K,…… if (newMS.Length > ImageMaxSize) { max = middle; } else { min = middle; new_height = middle_height; new_width = middle_width; //如果图片大小误差10K内就不再循环 if (ImageMaxSize - newMS.Length < 10 * 1024) { break; } } } ms = CompressImageMemoryStream(ms, new_height, new_width); } /* * 缩小缓冲区长度,因为数据库中存储的长度是根据缓冲区的长度得到的。 * Capacity 是系统提供的字节数组的缓冲区长度。Capacity 无法设置为小于流的当前长度的值。 * */ //缓冲区长度 ms.Capacity = (int)ms.Length; buffer = ms.GetBuffer(); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { if (ms != null) { ms.Close(); } ms = null; } return buffer; } /// <summary> /// 将MemoryStream中的图像按照给定高、宽进行压缩 /// </summary> /// <param name="ms">存图像的MemoryStream</param> /// <param name="new_height">设置的高度</param> /// <param name="new_width">设置的宽度</param> /// <returns>返回存放经过压缩的图像的MemoryStream</returns> private static MemoryStream CompressImageMemoryStream(MemoryStream ms, double new_height, double new_width) { Image m_src_image = Image.FromStream(ms); Bitmap bbmp = new Bitmap((int)new_width, (int)new_height, m_src_image.PixelFormat); Graphics graphics = Graphics.FromImage(bbmp); graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; graphics.DrawImage(m_src_image, 0, 0, bbmp.Width, bbmp.Height); ms = new MemoryStream(); bbmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); ms.Flush(); return ms; } } }