private void pbOriginal_LoadCompleted(object sender, AsyncCompletedEventArgs e)
        {
            unlock_img.Dispose();

            lblPreLoading.Visible = true;
            lblPreLoading.Text    = "ЗАГРУЗКА ...";
            stFooterChild2.Text   = "satus: img loading";
            this.Update();
            btnAply.Enabled = true;
            Stopwatch stopWatch = new Stopwatch();

            stopWatch.Start();
            lblImgWidth.Text = "width: " + pbOriginal.Image.Width + " height: " + pbOriginal.Image.Height;
            image_width      = pbOriginal.Image.Width;
            image_height     = pbOriginal.Image.Height;

            unlock_img = new ImagePix(image_width, image_height);

            if (image_height < cache_size || image_width < cache_size)
            {
                cache_size = Math.Min(image_height, image_width);
            }
            else if (cache_size != default_cach)
            {
                cache_size = default_cach;
            }

            Bitmap img = new Bitmap(pbOriginal.Image);

            pbResault.Image    = img;
            lblPreLoading.Text = "ПОДГОТОВКА ...";
            this.Update();
            for (int new_height = 0; new_height < image_height; new_height += 1)
            {
                for (int new_width = 0; new_width < image_width; new_width += 1)
                {
                    unlock_img.SetPixel(new_width, new_height, img.GetPixel(new_width, new_height));
                }
            }
            Console.WriteLine(unlock_img.GetPixel(4, 4).R + "; " + unlock_img.width);
            lblPreLoading.Visible = false;
            stFooterChild2.Text   = "satus: img load - OK";
            this.Update();
            stopWatch.Stop();
            TimeSpan ts = stopWatch.Elapsed;

            stFooterChild3.Text = "time load img: " + (ts.Seconds * 1000 + ts.Milliseconds).ToString() + "ms";
        }
        private void button1_Click(object sender, EventArgs e)
        {
            lblLoading.Visible = true;
            btnAply.Enabled    = false;
            this.Update();
            int val = (int)nudConvSize.Value;

            int[] conv_matrix = new int[val * val];
            for (int i = 0; i < val * val; i++)
            {
                conv_matrix[i] = (int)numud_list.ElementAt(i).Value;
            }
            //Bitmap img = new Bitmap(pbOriginal.Image);
            ImagePix n_img = apply_conv_matrix(conv_matrix, unlock_img);

            pbResault.Image = n_img.bitmap;
            //img.Dispose();
        }
        /// <summary>
        /// Применение свёртки к изображению
        /// </summary>
        /// <param name="conv_array">Массив Flatten матрицы свёртки</param>
        /// <param name="img">Массив Flatten изображения</param>
        public ImagePix apply_conv_matrix(int[] conv_array, ImagePix img)
        {
            Stopwatch stopWatch2 = new Stopwatch();

            stopWatch2.Start();
            ImagePix new_img = new ImagePix(image_width, image_height);

            for (int chl = 0; chl < 3; chl++)
            {
                for (int new_height = cache_size; new_height < image_height + cache_size - 1; new_height += cache_size)
                {
                    if (new_height > image_height)
                    {
                        new_height = image_height;
                    }
                    for (int new_width = cache_size; new_width < image_width + cache_size - 1; new_width += cache_size)
                    {
                        if (new_width > image_width)
                        {
                            new_width = image_width;
                        }
                        int[] img_array = new int[cache_size * cache_size];

                        for (int i = new_width - cache_size; i < new_width; i++)
                        {
                            for (int j = new_height - cache_size; j < new_height; j++)
                            {
                                if (chl == 0)
                                {
                                    img_array[1 * ((i % cache_size) * cache_size + (j % cache_size))] = img.GetPixel(i, j).R;
                                }
                                else if (chl == 1)
                                {
                                    img_array[1 * ((i % cache_size) * cache_size + (j % cache_size))] = img.GetPixel(i, j).G;
                                }
                                else
                                {
                                    img_array[1 * ((i % cache_size) * cache_size + (j % cache_size))] = img.GetPixel(i, j).B;
                                }
                            }
                        }
                        GCHandle handle_image = GCHandle.Alloc(img_array, GCHandleType.Pinned);
                        GCHandle handle_conv  = GCHandle.Alloc(conv_array, GCHandleType.Pinned);
                        try
                        {
                            IntPtr pointer_img  = handle_image.AddrOfPinnedObject();
                            IntPtr pointer_conv = handle_conv.AddrOfPinnedObject();
                            int[]  res          = new int[cache_size * cache_size];
                            IntPtr c;
                            try
                            {
                                c = calcConvolutionCuda(cache_size, cache_size, pointer_img, pointer_conv, (int)Math.Sqrt(conv_array.Length));
                            }catch (System.AccessViolationException e)
                            {
                                Console.WriteLine(e.Message);
                                return(null);
                            }

                            Marshal.Copy(c, res, 0, cache_size * cache_size);
                            for (int i = (new_width - 1) / cache_size * cache_size; i < new_width; i++)
                            {
                                for (int j = (new_height - 1) / cache_size * cache_size; j < new_height; j++)
                                {
                                    int   r  = res[i % cache_size * cache_size + (j % cache_size)];
                                    Color cl = new_img.GetPixel(i, j);
                                    if (chl == 0)
                                    {
                                        new_img.SetPixel(i, j, Color.FromArgb(r, cl.G, cl.B));
                                    }
                                    else if (chl == 1)
                                    {
                                        new_img.SetPixel(i, j, Color.FromArgb(cl.R, r, cl.B));
                                    }
                                    else
                                    {
                                        new_img.SetPixel(i, j, Color.FromArgb(cl.R, cl.G, r));
                                    }
                                }
                            }
                        }
                        finally
                        {
                            if (handle_image.IsAllocated)
                            {
                                handle_image.Free();
                            }
                            if (handle_conv.IsAllocated)
                            {
                                handle_conv.Free();
                            }
                        }
                    }
                }
            }
            stopWatch2.Stop();
            TimeSpan ts2 = stopWatch2.Elapsed;

            stFooterChild4.Text = "time edit img: " + (ts2.Seconds * 1000 + ts2.Milliseconds).ToString() + "ms";
            stFooterChild2.Text = "satus: img edit";
            lblLoading.Visible  = false;
            btnAply.Enabled     = true;
            this.Update();
            return(new_img);
        }