using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace YC.Common.ShareUtils
{
    public class ImageUtils
    {
        /// <summary>
        /// 生成缩略图操作
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static System.Drawing.Image GetImage(string path, int width, int height)
        {
            //System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.Open);
            //System.Drawing.Image result = System.Drawing.Image.FromStream(fs);

            CreateImageClass tempImage = new CreateImageClass(path);

            return tempImage.GetReducedImage(width, height);
        }

        /// <summary>
        /// Image转byte[]
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        public static byte[] ImageToBytes(Image image)
        {
            ImageFormat format = image.RawFormat;
            using (MemoryStream ms = new MemoryStream())
            {
                image.Save(ms, ImageFormat.Png);
                byte[] buffer = new byte[ms.Length];
                //Image.Save()会改变MemoryStream的Position，需要重新Seek到Begin
                ms.Seek(0, SeekOrigin.Begin);
                ms.Read(buffer, 0, buffer.Length);
                return buffer;
            }
        }

        /// <summary>
        /// Byte[]转Image
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static Image BytesToImage(byte[] buffer)
        {
            MemoryStream ms = new MemoryStream(buffer);
            Image image = Image.FromStream(ms);
            return image;
        }

        public static Bitmap GetImageFromBase64(string base64string)
        {
            byte[] b = Convert.FromBase64String(base64string);
            MemoryStream ms = new MemoryStream(b);
            Bitmap bitmap = new Bitmap(ms);
            return bitmap;
        }

        public static string GetBase64FromImage(string imagefile, bool includePrefix = true)
        {
            string strBaser64 = "";
            try
            {
                Bitmap bmp = new Bitmap(imagefile);
                MemoryStream ms = new MemoryStream();
                bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] arr = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length);
                ms.Close();
                if (includePrefix)
                {
                    strBaser64 = "data:imge/jpeg;base64," + Convert.ToBase64String(arr);
                }
                else
                {
                    strBaser64 = Convert.ToBase64String(arr);
                }
            }
            catch (Exception)
            {
                throw new Exception("Something wrong during convert!");
            }
            return strBaser64;
        }

        public static string GetImageJson(string path) {
            //测试保存图片地址
            string savePath = System.Environment.CurrentDirectory + "\\"+Guid.NewGuid().ToString()+"jpg";
            byte[] bytes = File.ReadAllBytes(path);

            //二进制转字符串
            string base64String = Convert.ToBase64String(bytes);
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(base64String);
            string deserializeBase64String = Newtonsoft.Json.JsonConvert.DeserializeObject<string>(json);
            if (base64String == deserializeBase64String)
            {
                Console.WriteLine("转换json成功！");
                //字符串转二进制
                byte[] newBytes = Convert.FromBase64String(deserializeBase64String);
                FileStream fileStream = null;
                try
                {
                   
                    fileStream = File.Create(savePath);
                    //FileStream.Write Method:Writes a block of bytes to the file stream.
                    fileStream.Write(newBytes, 0, newBytes.Length);
                    //FileStream.Flush 方法:清除该流的所有缓冲区，使得所有缓冲的数据都被写入到基础设备。
                    fileStream.Flush();
                    //FileStream.Close Method:Closes the file and releases any resources associated with the current file stream.
                    fileStream.Close();

                }
                catch (Exception ex)
                {
                    throw ex;

                }
            }
            else
            {
                return null; 
            }

            return json;
        }
    }

    public static class ImageEx
    {
        /// <summary>
        /// 图片旋转扩展
        /// </summary>
        /// <param name="img"></param>
        /// <param name="angle">转多少度</param>
        /// <returns></returns>
        public static System.Drawing.Image GetRotateImage(this System.Drawing.Image img, float angle)
        {
            angle = angle % 360;//弧度转换

            double radian = angle * Math.PI / 180.0;

            double cos = Math.Cos(radian);

            double sin = Math.Sin(radian);

            //原图的宽和高

            int w = img.Width;

            int h = img.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)));

            //目标位图

            System.Drawing.Image dsImage = new System.Drawing.Bitmap(W, H, img.PixelFormat);

            using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(dsImage))
            {
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;

                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

                //计算偏移量

                System.Drawing.Point Offset = new System.Drawing.Point((W - w) / 2, (H - h) / 2);

                //构造图像显示区域：让图像的中心与窗口的中心点一致

                System.Drawing.Rectangle rect = new System.Drawing.Rectangle(Offset.X, Offset.Y, w, h);

                System.Drawing.Point center = new System.Drawing.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(img, rect);

                //重至绘图的所有变换

                g.ResetTransform();

                g.Save();
            }

            return dsImage;
        }
    }

    /// <summary>
    /// 图片处理类
    /// 1、生成缩略图片或按照比例改变图片的大小和画质
    /// 2、将生成的缩略图放到指定的目录下
    /// </summary>
    public class CreateImageClass
    {
        public Image ResourceImage;
        private int ImageWidth;
        private int ImageHeight;
        public string ErrMessage;

        /// <summary>
        /// 类的构造函数
        /// </summary>
        /// <param name="ImageFileName">图片文件的全路径名称</param>
        public CreateImageClass(string ImageFileName)
        {
            //ResourceImage = Image.FromFile(ImageFileName);//会占用

            #region 1、多线程 无法

            System.IO.FileStream fs = new System.IO.FileStream(ImageFileName, FileMode.Open);
            System.Drawing.Image result = System.Drawing.Image.FromStream(fs);

            fs.Close();

            #endregion 1、多线程 无法

            ResourceImage = result;
            ErrMessage = "";
        }

        public bool ThumbnailCallback()
        {
            return false;
        }

        /// <summary>
        /// 生成缩略图重载方法1，返回缩略图的Image对象
        /// </summary>
        /// <param name="Width">缩略图的宽度</param>
        /// <param name="Height">缩略图的高度</param>
        /// <returns>缩略图的Image对象</returns>
        public Image GetReducedImage(int Width, int Height)
        {
            try
            {
                Image ReducedImage;
                Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback);
                ReducedImage = ResourceImage.GetThumbnailImage(Width, Height, callb, IntPtr.Zero);
                return ReducedImage;
            }
            catch (Exception e)
            {
                ErrMessage = e.Message;
                return null;
            }
        }

        /// <summary>
        /// 生成缩略图重载方法2，将缩略图文件保存到指定的路径
        /// </summary>
        /// <param name="Width">缩略图的宽度</param>
        /// <param name="Height">缩略图的高度</param>
        /// <param name="targetFilePath">缩略图保存的全文件名，(带路径)，参数格式：D:Images ilename.jpg</param>
        /// <returns>成功返回true，否则返回false</returns>
        public bool GetReducedImage(int Width, int Height, string targetFilePath)
        {
            try
            {
                Image ReducedImage;
                Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback);
                ReducedImage = ResourceImage.GetThumbnailImage(Width, Height, callb, IntPtr.Zero);
                ReducedImage.Save(@targetFilePath, ImageFormat.Jpeg);
                ReducedImage.Dispose();
                return true;
            }
            catch (Exception e)
            {
                ErrMessage = e.Message;
                return false;
            }
        }

        /// <summary>
        /// 生成缩略图重载方法3，返回缩略图的Image对象
        /// </summary>
        /// <param name="Percent">缩略图的宽度百分比 如：需要百分之80，就填0.8</param>
        /// <returns>缩略图的Image对象</returns>
        public Image GetReducedImage(double Percent)
        {
            try
            {
                Image ReducedImage;
                Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback);
                ImageWidth = Convert.ToInt32(ResourceImage.Width * Percent);
                ImageHeight = Convert.ToInt32(ResourceImage.Width * Percent);
                ReducedImage = ResourceImage.GetThumbnailImage(ImageWidth, ImageHeight, callb, IntPtr.Zero);
                return ReducedImage;
            }
            catch (Exception e)
            {
                ErrMessage = e.Message;
                return null;
            }
        }

        /// <summary>
        /// 生成缩略图重载方法4，返回缩略图的Image对象
        /// </summary>
        /// <param name="Percent">缩略图的宽度百分比 如：需要百分之80，就填0.8</param>
        /// <param name="targetFilePath">缩略图保存的全文件名，(带路径)，参数格式：D:Images ilename.jpg</param>
        /// <returns>成功返回true,否则返回false</returns>
        public bool GetReducedImage(double Percent, string targetFilePath)
        {
            try
            {
                Image ReducedImage;
                Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback);
                ImageWidth = Convert.ToInt32(ResourceImage.Width * Percent);
                ImageHeight = Convert.ToInt32(ResourceImage.Width * Percent);
                ReducedImage = ResourceImage.GetThumbnailImage(ImageWidth, ImageHeight, callb, IntPtr.Zero);
                ReducedImage.Save(@targetFilePath, ImageFormat.Jpeg);
                ReducedImage.Dispose();
                return true;
            }
            catch (Exception e)
            {
                ErrMessage = e.Message;
                return false;
            }
        }
    }
}