void ProcessImage(string image_file, int image_index)
        {
            mrePauseResume.WaitOne();

            this.Invoke((MethodInvoker) delegate()
            {
                labCurrentFile.Text = image_file;
                this.Refresh();
            });

            FileInfo fi = new FileInfo(image_file);

            if (!fi.Exists)
            {
                LogError("File doesn't exist", "Location: " + image_file);
                return;
            }

            //Calculate output file


            string out_file_name = fi.FullName;

            if (this.DoRename)
            {
                out_file_name = out_file_name.Replace(fi.Name, this.RenamePrefix + fi.Directory.Name + "_" + image_index.ToString(4) + this.OutputFileExtension);
            }
            else
            {
                out_file_name = out_file_name.Replace(fi.Extension, "") + this.OutputFileExtension;
            }

            string   out_file_path = this.DestinationFolderPath.TrimEnd('\\') + @"\" + GetRelativePath(out_file_name, this.SourceFolderPath);
            FileInfo ofi           = new FileInfo(out_file_path);

            if (!ofi.Directory.Exists)
            {
                ofi.Directory.Create();
            }

            using (Bitmap bmp = (Bitmap)Image.FromFile(fi.FullName))
            {
                Bitmap _processed = bmp;

                try
                {
                    int width  = bmp.Width,
                        height = bmp.Height;

                    BitmapProcessor bmpp = new BitmapProcessor(bmp);

                    if (this.ApplyConvolution)
                    {
                        bmpp.GrayscaleInverseConvolve3x3(this.ConvolutionMatrix);
                    }

                    if (this.DoBinarize)
                    {
                        if (this.DetermineBinarizationThresholdAutomatically)
                        {
                            bmpp.Binarise();
                        }
                        else
                        {
                            bmpp.Binarise(this.BinarizationThreshold);
                        }

                        _processed = bmp;
                    }

                    if (this.DoCropToFit)
                    {
                        var rect = bmpp.GetFittingRectangle(Color.White, this.CropMargin);
                        _processed = (Bitmap)bmp.Clone(rect, bmp.PixelFormat);
                    }

                    if (this.DoResize)
                    {
                        using (Bitmap resized = new Bitmap(this.ResizeWidth, this.ResizeHeight))
                        {
                            using (Graphics g = Graphics.FromImage(resized))
                            {
                                g.FillRectangle(new SolidBrush(Color.White), 0, 0, resized.Width, resized.Height);

                                //Calculate aspect
                                int _w = _processed.Width,
                                    _h = _processed.Height;
                                int _nw, _nh;
                                int margin_x, margin_y;

                                double aspect_w = (double)_w / (double)this.ResizeWidth;
                                double aspect_h = (double)_h / (double)this.ResizeHeight;

                                double max = Math.Max(aspect_w, aspect_h);
                                //double min = Math.Min(aspect_w, aspect_h);
                                double resize_factor = 1 / max;

                                _processed = _processed.Resize(resize_factor);
                                _nw        = _processed.Width;
                                _nh        = _processed.Height;

                                margin_x = (this.ResizeWidth - _nw) / 2;
                                margin_y = (this.ResizeHeight - _nh) / 2;

                                g.DrawImage(_processed, margin_x, margin_y);
                            }

                            _processed = (Bitmap)resized.Clone();
                        }
                    }

                    if (this.OutputPixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)
                    {
                        _processed = (Bitmap)_processed.Clone(new Rectangle(0, 0, _processed.Width, _processed.Height), this.OutputPixelFormat);
                    }

                    _processed.Save(out_file_path, this.OutputImageFormat);

                    _processed.Dispose();
                }
                catch (Exception ex)
                {
                    LogError(ex.Message);
                }
            }
        }