zoukankan      html  css  js  c++  java
  • C#

    旋转

    (1)按角度旋转

        /// <summary>  
        /// 根据角度旋转图标  
        /// </summary>  
        /// <param name="img"></param>  
        public Image RotateImg(Image img, float angle)  
        {  
            //通过Png图片设置图片透明,修改旋转图片变黑问题。  
            int width = img.Width;  
            int height = img.Height;                      
            //角度  
            Matrix mtrx = new Matrix();             
            mtrx.RotateAt(angle, new PointF((width / 2), (height / 2)), MatrixOrder.Append);  
            //得到旋转后的矩形  
            GraphicsPath path = new GraphicsPath();  
            path.AddRectangle(new RectangleF(0f, 0f, width, height));  
            RectangleF rct = path.GetBounds(mtrx);  
            //生成目标位图  
            Bitmap devImage = new Bitmap((int)(rct.Width), (int)(rct.Height));  
            Graphics g = Graphics.FromImage(devImage);  
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;  
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;             
            //计算偏移量  
            Point Offset = new Point((int)(rct.Width - width) / 2, (int)(rct.Height - height) / 2);  
            //构造图像显示区域:让图像的中心与窗口的中心点一致  
            Rectangle rect = new Rectangle(Offset.X, Offset.Y, (int)width, (int)height);  
            Point center = new Point((int)(rect.X + rect.Width / 2), (int)(rect.Y + rect.Height / 2));              
            g.TranslateTransform(center.X, center.Y);  
            g.RotateTransform(angle);  
            //恢复图像在水平和垂直方向的平移  
            g.TranslateTransform(-center.X, -center.Y);  
            g.DrawImage(img, rect);  
            //重至绘图的所有变换  
            g.ResetTransform();  
            g.Save();  
            g.Dispose();  
            path.Dispose();  
            return devImage;  
        } 
    

    (2)按弧度旋转

        /// <summary>  
        /// 第二种方法  
        /// </summary>  
        /// <param name="b"></param>  
        /// <param name="angle"></param>  
        /// <returns></returns>  
        public Image RotateImg2(Image b, float angle)  
        {  
            angle = angle % 360;            //弧度转换  
            double radian = angle * Math.PI / 180.0;  
            double cos = Math.Cos(radian);  
            double sin = Math.Sin(radian);  
            //原图的宽和高  
            int w = b.Width;  
            int h = b.Height;  
            int W = (int)(Math.Max(Math.Abs(w * cos - h * sin), Math.Abs(w * cos + h * sin)));  
            int H = (int)(Math.Max(Math.Abs(w * sin - h * cos), Math.Abs(w * sin + h * cos)));  
            //目标位图  
            Image dsImage = new Bitmap(W, H);  
            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(dsImage);  
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;  
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;  
            //计算偏移量  
            Point Offset = new Point((W - w) / 2, (H - h) / 2);  
            //构造图像显示区域:让图像的中心与窗口的中心点一致  
            Rectangle rect = new Rectangle(Offset.X, Offset.Y, w, h);  
            Point center = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);  
            g.TranslateTransform(center.X, center.Y);  
            g.RotateTransform(360-angle);  
            //恢复图像在水平和垂直方向的平移  
            g.TranslateTransform(-center.X, -center.Y);  
            g.DrawImage(b, rect);  
            //重至绘图的所有变换  
            g.ResetTransform();  
            g.Save();  
            g.Dispose();  
            //dsImage.Save("yuancd.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);  
            return dsImage;  
        }
    

    以上参考:基于C#的两种图片旋转方法

    此外,可以直接使用已封装的方法:

    /// <summary>  
    /// 旋转(利用已封装的方法) 
    /// </summary>  
    /// <param name="path">图片路径</param>  
    /// <param name="rotateFlipType">旋转方式</param>  
    /// <returns></returns>  
    public bool KiRotate(string path, RotateFlipType rotateFlipType)  
    {  
        try  
        {  
            using (Bitmap bitmap = new Bitmap(path))  
            {  
                // 顺时针旋转90度 RotateFlipType.Rotate90FlipNone
                // 逆时针旋转90度 RotateFlipType.Rotate270FlipNone
                // 水平翻转 RotateFlipType.Rotate180FlipY
                // 垂直翻转 RotateFlipType.Rotate180FlipX
                bitmap.RotateFlip(rotateFlipType);  
                bitmap.Save(path);  
            }  
            return true;  
        }  
        catch(Exception ex)  
        {  
            return false;  
        }  
    } 
    

    转换

    (1)Bitmap & BitmapImage

    // 程序集
    System.Xaml.dll
    System.Drawing.dll
    WindowsBase.dll
    PresentationCore.dll
    // 命名空间
    using System.Drawing;
    using System.IO;
    using System.Windows.Media.Imaging;
    using System.Windows.Interop;
    using System.Windows;
    
    /// <summary>
    /// 创建一个Bitmap对象
    /// </summary>
    /// <param name="_uri">"../Images/test.png"</param>
    public Bitmap CreatBitmapObject(string _uri)
    {
        Bitmap bitmap = new Bitmap(_uri);
        return bitmap;
    }
    
    /// <summary>
    /// 创建一个BitmapImage对象
    /// </summary>
    /// <param name="_uri">"../Images/test.png"</param>
    public BitmapImage CreatBitmapImageObject(string _uri)
    {
        BitmapImage bitmapImage = new BitmapImage(
            new Uri(_uri, UriKind.Relative));
        return bitmapImage;
    }
    
    /// <summary>
    /// BitmapImage to Bitmap
    /// </summary>
    public Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage)
    {
    	using (MemoryStream outStream = new MemoryStream())
    	{
    		BitmapEncoder enc = new BmpBitmapEncoder();
    		enc.Frames.Add(BitmapFrame.Create(bitmapImage));
    		enc.Save(outStream);
    		Bitmap bitmap = new Bitmap(outStream);
    		return new Bitmap(bitmap);
    	}
    }
    
    /// <summary>
    /// Bitmap to BitmapImage
    /// </summary>
    [System.Runtime.InteropServices.DllImport("gdi32.dll")]
    public static extern bool DeleteObject(IntPtr hObject);
    public BitmapImage Bitmap2BitmapImage(Bitmap bitmap)
    {
    	IntPtr hBitmap = bitmap.GetHbitmap();
    	BitmapImage retval;
    
    	try
    	{
    		retval = (BitmapImage)Imaging.CreateBitmapSourceFromHBitmap(
    				hBitmap, IntPtr.Zero, Int32Rect.Empty,
    				BitmapSizeOptions.FromEmptyOptions());
    	}
    	finally
    	{
    		DeleteObject(hBitmap);
    	}
    
    	return retval;
    }
    

    若是将Bitmap转换成BitmapSource,只需将返回值类型更改为BitmapSource即可。

    具体参考:Converting BitmapImage to Bitmap and vice versa

    (2)Bitmap/BitmapImage & byte[]

    /// <summary>
    /// Bitmap to 字节数组
    /// </summary>
    public byte[] Bitmap2Bytes(Bitmap bitmap)
    {
    	ImageFormat format = bitmap.RawFormat;
    	using (MemoryStream ms = new MemoryStream())
    	{
    		bitmap.Save(ms, format);
    		byte[] data = new byte[ms.Length];
    		//Save()会改变MemoryStream的Position,需要重新Seek到Begin也就是开始的0位置
    		ms.Seek(0, SeekOrigin.Begin);
    		ms.Read(data, 0, Convert.ToInt32(ms.Length));
    		return data;  
    	}
    }
    /// <summary>
    /// 字节数组 to Bitmap
    /// </summary>
    public Bitmap Bytes2Bitmap(byte[] data)
    {
    	MemoryStream ms = null;
    	try
    	{
    		ms = new MemoryStream(data);
    		return new Bitmap((Image)new Bitmap(ms));
    	}
    	catch (Exception ex)
    	{
    		throw ex;   
    	}
    	finally
    	{
    		ms.Close();
    	}
    }
    
    /// <summary>
    /// BitmapImage to 字节数组
    /// </summary>
    public byte[] BitmapImage2Bytes(BitmapImage bitmapImage)
    {
    	byte[] bytes = null;
    	try
    	{
    		Stream ms = bitmapImage.StreamSource;
    		if (ms != null && ms.Length > 0)
    		{
    			//很重要,因为Position经常位于stream的末尾,导致下面读取到的长度为0
    			ms.Position = 0;
    			using (BinaryReader br = new BinaryReader(ms))
    			{
    				bytes = br.ReadBytes((int)ms.Length);
    			} 
    		}
    	}
    	catch(Exception ex)
    	{
    		bytes = null;
    		throw ex;
    	}
    	return bytes;
    }
    /// <summary>
    /// 字节数组 to BitmapImage
    /// </summary>
    public BitmapImage Bytes2BitmapImage(byte[] data)
    {
    	BitmapImage bitmapImage = null;
    	try
    	{
    		bitmapImage = new BitmapImage();
    		bitmapImage.BeginInit();
    		bitmapImage.StreamSource = new MemoryStream(data);
    		bitmapImage.EndInit();
    	}
    	catch(Exception ex)
    	{
    		bitmapImage = null;
    		throw ex;  
    	}
    	return bitmapImage;
    }
    

    此时,可以总结下Bitmap、BitmapImage、Image和BitmapSource、ImageSource之间的关系

    // Image抽象类,Bitmap密封类
    public abstract class Image: xxx
    public sealed class Bitmap : Image
    // ImageSource和BitmapSource抽象类,BitmapImage密封类 
    public abstract class ImageSource: xxx
    public abstract class BitmapSource : ImageSource
    public sealed class BitmapImage : BitmapSource
    

    压缩

    图片大小 > 1M 时,可以对图片进行压缩,有效减小图片大小、占用内存空间等。

    /// <summary>
    /// 生成缩略图
    /// </summary>
    /// <param name="sourceFile">原始图片文件</param>
    /// <param name="quality">质量压缩比:0-100,越大质量越好</param>
    /// <param name="multiple">压缩倍数</param>
    /// <param name="outputFile">输出文件名</param>
    /// <returns>成功返回true,失败返回false</returns>
    /// 调用格式:GetThumImage("", 85L, 3, ""); 
    public static bool GetThumImage(string sourceFile, long quality, int multiple, string outputFile)
    {
    	try
    	{
    		// 获取图片信息
    		Bitmap sourceImage = new Bitmap(sourceFile);
    		ImageCodecInfo myImageCodecInfo = GetEncoderInfo(sourceImage.RawFormat);
    		if (null == myImageCodecInfo) {
    			return false;
    		}
    		
    		// 压缩质量
    		System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
    		EncoderParameters myEncoderParameters = new EncoderParameters(1);
    		EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, quality);
    		myEncoderParameters.Param[0] = myEncoderParameter;
    		
    		// 按比例压缩
    		float _xWidth = sourceImage.Width;
    		float _yWidth = sourceImage.Height;
    		Bitmap newImage = new Bitmap((int)(_xWidth / multiple), (int)(_yWidth / multiple));
    		Graphics g = Graphics.FromImage(newImage);
    		/// 可按需配置属性
    		//g.CompositingQuality = CompositingQuality.HighQuality;
    		//g.CompositingMode = CompositingMode.SourceCopy;
    		//g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    		g.DrawImage(sourceImage, 0, 0, (_xWidth / multiple), (_yWidth / multiple));
    		g.Dispose();
    
    		// 保存图片
    		newImage.Save(outputFile, myImageCodecInfo, myEncoderParameters);                
    		return true;
    	}
    	catch
    	{
    		return false;
    	}
    }
    
    /// <summary>
    /// 获取图片编码信息
    /// </summary>
    private static ImageCodecInfo GetEncoderInfo(ImageFormat format)
    {
    	ImageCodecInfo[] encoders;
    	encoders = ImageCodecInfo.GetImageEncoders();
    	for (int j = 0; j < encoders.Length; ++j)
    	{
    		if (encoders[j].FormatID == format.Guid) {
    			return encoders[j];
    		}
    	}
    	return null;
    }
    

    提供一个在工作中压缩图片的方法

    public string CompressImageString(string str) {
        string convertedImageString = string.Empty;
        byte[] b = Convert.FromBase64String(str);
        MemoryStream ms = new MemoryStream(b);
        Bitmap bitMap = new Bitmap(ms);
        bitMap = CompressImage(bitMap);
        byte[] byteArray = null;
        using (MemoryStream stream = new MemoryStream()) {
            bitMap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
            byteArray = new byte[stream.Length];
            stream.Seek(0, SeekOrigin.Begin);
            if (stream.Read(byteArray, 0, Convert.ToInt32(stream.Length)) <= 0)
            {
                return "";
            }
        }           
        convertedImageString = Convert.ToBase64String(byteArray);           
        return convertedImageString;
    }
    private Bitmap CompressImage(Bitmap bitmap, double compressRatio) {
        int width = (int)(bitmap.Width * compressRatio);
        int height = (int)(bitmap.Height * compressRatio);
        System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
        System.Drawing.Image myThumbnail = bitmap.GetThumbnailImage(width, height, myCallback, IntPtr.Zero);
        Bitmap compressBitmap = new Bitmap(myThumbnail);
        return compressBitmap;
    }
    public bool ThumbnailCallback() { return false; }
    

    Base64处理

    最常见的用于传输8Bit字节码的编码方式之一,可以将任意一组字节转换为较长的常见文本字符序列,从而可以合法地作为首部字段值

    • Base64:一种基于64个可打印字符以及用作后缀的等号来表示二进制数据的方法
    • Base64编码:从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息
    • 编码规则:每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3个字符变成4个字符,每76个字符加一个换行符,最后的结束符也要处理

    其中,64个可打印字符包括:大小写字母、数字、 + 和 / 。相关特点:

    • 把含有不可见字符串的信息用可见字符串表示出来、降低出错率,但具有不可读性、需解码
    • 二进制序列的长度必须是24的倍数(6和8的最小公倍数)
    • 等号一定用作后缀,且数目一定是0个、1个或2个
    • 因为将3个字节转化成4个字节,因此编码后的文本,会比原文本大出三分之一左右
    ['A', 'B', 'C', 'D', ... 'a', 'b', 'c', 'd', ... '0', '1', '2', ... '+', '/']
    

    注意,标准的Base64编码存在 '+'和 '/',针对URL,通过"url safe"的base64编码,将 '+'和 '/' 分别变成 '-'和 '_',同时会删除结果最后的 '='

    >>> base64.b64encode('ixb7x1dxfbxefxff')
    'abcd++//'
    >>> base64.urlsafe_b64encode('ixb7x1dxfbxefxff')
    'abcd--__'
    

    对于二进制序列长度必须是24倍数的解释:正常情况下,只要长度是6的倍数即可。但是,当连接两段Base64编码过的字符串后再解码,这个时候就需要6和8的公倍数,即长度必须是24的倍数。

    现在浏览器已有内置的自动生成base64的方法 atob() btoa()

    // 编码
    window.btoa()
    // 解码
    window.atob()
    

    具体参见:window.btoa()window.atob()

    注意,待编码字符串若包含中文,直接编码会出现问题,应采用如下方式

    function utf8_to_b64( str ) {
    	return window.btoa(
    		unescape(
    			encodeURIComponent( str )));
    }
    function b64_to_utf8( str ) {
    	return decodeURIComponent(
    		escape(
    			window.atob( str )));
    } 
    

    参考

  • 相关阅读:
    绿色简洁供应商采购后台管理系统模板——后台
    通用的电子商务商城后台管理界面模板——后台
    透明的企业网站卡通后台模板——后台
    绿色的宠物店cms后台管理系统模板——后台
    蓝色的cms企业记账管理后台模板源码——后台
    简洁的响应式博客后台管理模板——后台
    基于bootstrap物资管理系统后台模板——后台
    黑色的网站后台管理系统ui界面——后台
    蓝色的企业后台cms管理系统——后台
    黑色的cms商城网站后台管理模板——后台
  • 原文地址:https://www.cnblogs.com/wjcx-sqh/p/8143508.html
Copyright © 2011-2022 走看看