using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Mosaic
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private double compareimg(int[] s1,int[] s2)
        {
            int s = 0, a = 0, b = 0;
            for (int i = 0; i < 64; i++)
            {
                s += s1[i] * s2[i];
                a += s1[i] * s1[i];
                b += s2[i] * s2[i];
            }
            double sa = Math.Sqrt(a);
            double sb = Math.Sqrt(b);
            double resultnum = s / (sa * sb);
            return resultnum;
        }


        private void cutimage(string orgpath,int sx,int sy)
        {
            
            Image orgimg = Image.FromFile(orgpath);
            Bitmap bmp = new Bitmap(x, y);
            Graphics gra = Graphics.FromImage(bmp);
            gra.DrawImage(orgimg, 0, 0, new Rectangle(sx, sy, x, y), GraphicsUnit.Pixel);//sx,sy为被剪图形的起始位置；
            Image saveimg = Image.FromHbitmap(bmp.GetHbitmap());
            saveimg.Save("run.jpg", ImageFormat.Jpeg);

            orgimg.Dispose();
            bmp.Dispose();
            gra.Dispose();
            saveimg.Dispose();

        }

        private int[] getimgindex(Color cl)
        {
            int[] index= new int[3];
            int r = cl.R, g = cl.G, b = cl.B;

            if (r >= 0 && r < 64) index[0] = 0;
            if (g >= 0 && g < 64) index[1] = 0;
            if (b >= 0 && b < 64) index[2] = 0;

            if (r >= 64 && r < 128) index[0] = 1;
            if (g >= 64 && g < 128) index[1] = 1;
            if (b >= 64 && b < 128) index[2] = 1;

            if (r >= 128 && r < 192) index[0] = 2;
            if (g >= 128 && g < 192) index[1] = 2;
            if (b >= 128 && b < 192) index[2] = 2;

            if (r >= 192 && r < 256) index[0] = 3;
            if (g >= 192 && g < 256) index[1] = 3;
            if (b >= 192 && b < 256) index[2] = 3;

            return index;
        }

        private int[] getimginfo(string imgpath)
        {
            Bitmap bmp1 = new Bitmap(imgpath);
            Bitmap bmp = new Bitmap(bmp1, x, y);
           
            int w = bmp.Width, h = bmp.Height;
            Color color = new Color();
            int[,,] colorinfo = new int[4,4,4];
            for (int i = 0; i < w; i++)
            {
                for (int j = 0; j < h; j++)
                {
                    color = bmp.GetPixel(i, j);
                    int[] idx = getimgindex(color);
                    colorinfo[idx[0], idx[1], idx[2]]++;
                }
            }
            int[] finger = new int[64];
            int count = 0;
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    for (int k = 0; k < 4; k++)
                    {
                        finger[count] = colorinfo[i, j, k];
                        count++;
                    }
                }
            }
            bmp.Dispose();
            bmp1.Dispose();
            
            return finger;
        }




        int x = 20, y = 20;
        List<string> bigconnect = new List<string>();
        List<int[]> biggallery = new List<int[]>();
        List<int[]> gallery = new List<int[]>();
        List<string> connect = new List<string>();
        int bigx, bigy;
        int ox, oy;

        private void button2_Click(object sender, EventArgs e)
        {
            //string bigpath = @"C:\Users\杨思英\Desktop\picpjt\test5.jpg";
            string bigpath = textBox3.Text;
            Image bigimg = Image.FromFile(bigpath);
            ox = bigimg.Width;
            oy = bigimg.Height;
            bigx = bigimg.Width / x;
            bigy = bigimg.Height / y;

            biggallery = new List<int[]>();
            bigconnect = new List<string>();

            for (int i = 0; i < bigy; i++)
            {
                for (int j = 0; j < bigx; j++)
                {
                    
                    cutimage(bigpath, x * j, y * i);
                    textBox1.AppendText("读取：第" + i + "，" + j + "块\n");
                    biggallery.Add(getimginfo("run.jpg"));
                    textBox1.AppendText("处理：第" + i + "，" + j + "块\n");

                }
            }
            textBox1.AppendText("read OK\n");
            
        }

        private void button4_Click(object sender, EventArgs e)
        {
            this.Invoke(new Action(() => { button4.Enabled = false; }));
            Thread bt = new Thread(new ThreadStart(MixBt));
            bt.Start();
        }

        private void textBox2_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            FolderBrowserDialog dilog = new FolderBrowserDialog();
            dilog.Description = "选择图库文件夹";
            if (dilog.ShowDialog() == DialogResult.OK ) 
            {
                textBox2.Text = dilog.SelectedPath;
            }
        }

        private void textBox3_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            OpenFileDialog filedilog = new OpenFileDialog();
            filedilog.Multiselect = false;
            filedilog.Title = "样版图片";
            filedilog.Filter = "图片|*.jpg;*.bmp;*.png";
            filedilog.RestoreDirectory = true;
            if(filedilog.ShowDialog()==DialogResult.OK)
            {
                textBox3.Text = filedilog.FileName;
            }
        }

        private void MixBt()
        {
            x = Convert.ToInt32(textBox6.Text);
            y = Convert.ToInt32(textBox7.Text);
            DirectoryInfo picpath = new DirectoryInfo(textBox2.Text);
            //DirectoryInfo picpath = new DirectoryInfo(@"C: \Users\杨思英\Desktop\picpjt\V");
            FileInfo[] fileinfo = picpath.GetFiles("*.*", SearchOption.AllDirectories);

            gallery = new List<int[]>();
            connect = new List<string>();
            int c = 0;
            foreach (var item in fileinfo)
            {
                if (Formatjug(item)==false)
                {
                    continue;
                }
                connect.Add(item.FullName);
                gallery.Add(getimginfo(connect[c]));
                this.Invoke(new Action(() => { textBox1.AppendText("处理：" + c.ToString() + ":" + item.Name + "\n"); }));
               // textBox1.AppendText("处理：" + c.ToString() + ":" + item.Name + "\n");
                //textBox1.ScrollToCaret();
                c++;
            }
            this.Invoke(new Action(() => { textBox1.AppendText("Read Image ok"); }));
            //textBox1.AppendText("Read Image ok");

            //string bigpath = @"C:\Users\杨思英\Desktop\picpjt\test5.jpg";
            string bigpath = textBox3.Text;
            Image bigimg = Image.FromFile(bigpath);
            ox = bigimg.Width;
            oy = bigimg.Height;
            bigx = bigimg.Width / x;
            bigy = bigimg.Height / y;

            biggallery = new List<int[]>();
            bigconnect = new List<string>();

            for (int i = 0; i < bigy; i++)
            {
                for (int j = 0; j < bigx; j++)
                {

                    cutimage(bigpath, x * j, y * i);
                    this.Invoke(new Action(() => { textBox1.AppendText("读取：第" + i + "，" + j + "块\n"); }));
                    //textBox1.AppendText("读取：第" + i + "，" + j + "块\n");
                    biggallery.Add(getimginfo("run.jpg"));
                    this.Invoke(new Action(() => { textBox1.AppendText("处理：第" + i + "，" + j + "块\n"); }));
                    //textBox1.AppendText("处理：第" + i + "，" + j + "块\n");

                }
            }
            this.Invoke(new Action(() => { textBox1.AppendText("read OK\n"); }));
            //textBox1.AppendText("read OK\n");



            int mul = Convert.ToInt32(textBox4.Text);
            Bitmap bmp = new Bitmap(ox * mul, oy * mul);
            Graphics gra = Graphics.FromImage(bmp);
            int co = 0;
            for (int i = 0; i < bigy; i++)
            {
                for (int j = 0; j < bigx; j++)
                {
                    double cur = -2;
                    double ck = -2;
                    int index = 0;
                    for (int k = 0; k < gallery.Count; k++)
                    {
                        ck = compareimg(biggallery[co], gallery[k]);
                        if (ck > cur)
                        {
                            index = k;
                            cur = ck;
                        }
                    }
                    this.Invoke(new Action(() => { textBox1.AppendText(co + "计算完成" + i + "," + j + "\n"); }));
                    //textBox1.AppendText(co + "计算完成" + i + "," + j + "\n");
                    co++;
                    //draw;
                    Image dw = Image.FromFile(connect[index]);
                    gra.DrawImage(dw, x * j * mul, y * i * mul, x * mul, y * mul);
                    dw.Dispose();
                    this.Invoke(new Action(() => { textBox1.AppendText(co + "拼接完成 " + i + "," + j + "\n"); }));
                    //textBox1.AppendText(co + "拼接完成 " + i + "," + j + "\n");
                }

            }
            this.Invoke(new Action(() => { textBox1.AppendText("All Done"); }));
            //textBox1.AppendText("all done");
            string imgname = textBox5.Text;
            Image saveimg = Image.FromHbitmap(bmp.GetHbitmap());
            saveimg.Save(imgname, ImageFormat.Jpeg);

            bmp.Dispose();
            gra.Dispose();

            this.Invoke(new Action(() => { button4.Enabled = true; }));
        }

        private bool Formatjug(FileInfo item)
        {
            string fmt = Path.GetExtension(item.FullName);
            string[] fmtlib = new string[]
            {
                ".jpg",".bmp",".png"
            };
            foreach (var eachexten in fmtlib)
            {
                if (fmt==eachexten)
                {
                    return true;
                }
            }
            return false;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            int mul = Convert.ToInt32(textBox4.Text);
            Bitmap bmp = new Bitmap(ox * mul, oy * mul);
            Graphics gra = Graphics.FromImage(bmp);
            int co = 0;
            for (int i = 0; i < bigy; i++)
            {
                for (int j = 0; j < bigx; j++)
                {
                    double cur = -2;
                    double ck = -2;
                    int index = 0;
                    for (int k = 0; k < gallery.Count; k++)
                    {
                        ck = compareimg(biggallery[co], gallery[k]);
                        if (ck > cur)
                        {
                            index = k;
                            cur = ck;
                        }
                    }
                    textBox1.AppendText(co + "计算完成" + i + "," + j + "\n");
                    co++;
                    //draw;
                    Image dw = Image.FromFile(connect[index]);
                    gra.DrawImage(dw, x * j * mul, y * i * mul, x * mul, y * mul);
                    dw.Dispose();
                    textBox1.AppendText(co + "拼接完成 " + i + "," + j + "\n");
                }
               
            }
            textBox1.AppendText("all done");
            string imgname = textBox5.Text;
            Image saveimg = Image.FromHbitmap(bmp.GetHbitmap());
            saveimg.Save(imgname, ImageFormat.Jpeg);

            bmp.Dispose();
            gra.Dispose();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            x = Convert.ToInt32(textBox6.Text);
            y = Convert.ToInt32(textBox7.Text);
            DirectoryInfo picpath = new DirectoryInfo(textBox2.Text);
            //DirectoryInfo picpath = new DirectoryInfo(@"C: \Users\杨思英\Desktop\picpjt\V");
            FileInfo[] fileinfo = picpath.GetFiles("*.*", SearchOption.AllDirectories);

            gallery = new List<int[]>();
            connect = new List<string>() ;
            int c = 0;
            foreach (var item in fileinfo)
            {
                
                connect.Add(item.FullName);
                gallery.Add(getimginfo(connect[c]));
                textBox1.AppendText("处理："+c.ToString()+":"+item.Name+"\n");
                //textBox1.ScrollToCaret();
                c++;
            }
            textBox1.AppendText("Read Image ok");
            //MessageBox.Show(gallery.Count.ToString());

            //MessageBox.Show(fileinfo.Length.ToString());
            //int[] index= getimginfo(@"C:\Users\杨思英\Desktop\picpjt\V\creat.png");
            //for (int i = 0; i < 64; i++)
            //{
            //    MessageBox.Show(index[i] + "  ");
            //}
        }
    }
}
