using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using OpenCvSharp;
using System.Drawing;
using System.IO;
using System.ComponentModel;
using Gdal = OSGeo.GDAL.Gdal;
using Ogr = OSGeo.OGR.Ogr;

namespace WpfApp5
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : System.Windows.Window
{
public MainWindow()
{
InitializeComponent();
GdalConfiguration.ConfigureGdal();
GdalConfiguration.ConfigureOgr();
Gdal.AllRegister();

        ds1 = null;
        ds2 = null;
        ds3 = null;

        band1 = null;
        band2 = null;
        band3 = null;

        zoomValue = 1;

        winWidth1 = (int)border1.Width;
        winHeight1 = (int)border1.Height;

        winWidth2 = (int)border2.Width;
        winHeight2 = (int)border2.Height;

        winWidth3 = (int)border3.Width;
        winHeight3 = (int)border3.Height;

        StartXpos = new MyTextshow();
        StartYpos = new MyTextshow();
        WidthSize = new MyTextshow();
        HeightSize = new MyTextshow();
        CursorXpos =  new MyTextshow();
        CursorYpos = new MyTextshow();
        LeftBtnXpos = new MyTextshow();
        LeftBtnYpos = new MyTextshow();

        StartXpos.Show = "0";
        StartYpos.Show = "0";
        WidthSize.Show = "0";
        HeightSize.Show = "0";
        CursorXpos.Show = "0";
        CursorYpos.Show = "0";
        LeftBtnXpos.Show = "0";
        LeftBtnYpos.Show = "0";

        startX1.DataContext = StartXpos;
        startY1.DataContext = StartYpos;
        width1.DataContext = WidthSize;
        height1.DataContext = HeightSize;
        cursorX.DataContext = CursorXpos;
        cursorY.DataContext = CursorYpos;
        LeftBtnClickcursorX.DataContext = LeftBtnXpos;
        LeftBtnClickcursorY.DataContext = LeftBtnYpos;
        //showRectangle = false;
        currentStretchRate = (double)nImgSizeX1 / (double)winWidth1;

    }


    public void DrawRect(System.Windows.Point pos)
    {
        double rect_size = 150 / currentStretchRate;
        if (ds1 != null)
        {
            System.Windows.Size a = new System.Windows.Size(rect_size, rect_size);
            var rect = new System.Windows.Rect(pos, a);
            Rectangle1.Margin = new Thickness(rect.Left, rect.Top, 0, 0);
            Rectangle1.Width = rect.Width;
            Rectangle1.Height = rect.Height;
        }

        if(ds2!=null )
        {
            System.Windows.Size a = new System.Windows.Size(rect_size, rect_size);
            var rect = new System.Windows.Rect(pos, a);
            Rectangle2.Margin = new Thickness(rect.Left, rect.Top, 0, 0);
            Rectangle2.Width = rect.Width;
            Rectangle2.Height = rect.Height;
        }

        if (ds3 != null)
        {
            System.Windows.Size a = new System.Windows.Size(rect_size, rect_size);
            var rect = new System.Windows.Rect(pos, a);
            Rectangle3.Margin = new Thickness(rect.Left, rect.Top, 0, 0);
            Rectangle3.Width = rect.Width;
            Rectangle3.Height = rect.Height;
        }
    }

    private void ShowImg(int startX,int startY,int showSizeX,int showSizeY)
    {
        System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
        if (ds1 != null)
        {
            stopwatch.Start();
            band1.ReadRaster(startX, startY, showSizeX, showSizeY, pData1, winWidth1, winHeight1, OSGeo.GDAL.DataType.GDT_UInt16, 0, 0);
            stopwatch.Stop();

            TimeSpan ts2 = stopwatch.Elapsed;
            int milliseconds = (int)ts2.TotalMilliseconds;
            //Console.WriteLine("time cost {0}", ts2.TotalMilliseconds);
            CursorYpos.Show = milliseconds.ToString();
            var pixelFormat1 = PixelFormats.Gray16;
            var bytesPerPixel1 = (pixelFormat1.BitsPerPixel + 7) / 8;
            var stride1 = bytesPerPixel1 * winWidth1;
            var bitmap1 = BitmapSource.Create(winWidth1, winHeight1, 72, 72,
                         pixelFormat1, null, pabyData1, stride1);

            WPFImage1.Source = bitmap1;
        }

        if (ds2 != null)
        {
            band2.ReadRaster(startX, startY, showSizeX, showSizeY, pData2, winWidth2, winHeight2, OSGeo.GDAL.DataType.GDT_UInt16, 0, 0);
            var pixelFormat2 = PixelFormats.Gray16;
            var bytesPerPixel2 = (pixelFormat2.BitsPerPixel + 7) / 8;
            var stride2 = bytesPerPixel2 * winWidth2;
            var bitmap2 = BitmapSource.Create(winWidth2, winHeight2, 72, 72,
                         pixelFormat2, null, pabyData2, stride2);

            WPFImage2.Source = bitmap2;
        }

        if (ds3 != null)
        {
            band3.ReadRaster(startX, startY, showSizeX, showSizeY, pData3, winWidth3, winHeight3, OSGeo.GDAL.DataType.GDT_UInt16, 0, 0);
            var pixelFormat3 = PixelFormats.Gray16;
            var bytesPerPixel3 = (pixelFormat3.BitsPerPixel + 7) / 8;
            var stride3 = bytesPerPixel3 * winWidth3;
            var bitmap3 = BitmapSource.Create(winWidth3, winHeight3, 72, 72,
                         pixelFormat3, null, pabyData3, stride3);

            WPFImage3.Source = bitmap3;
        }

        if (RectanglePos != null)
        {
            double refPosX1 = RectanglePos.X - imageStartX1;
            double refPosY1 = RectanglePos.Y - imageStartY1;

            //System.Windows.Point RectangleWinPos = new System.Windows.Point();
            RectangleWinPos.X = refPosX1 / currentStretchRate;
            RectangleWinPos.Y = refPosY1 / currentStretchRate;
            DrawRect(RectangleWinPos);
        }
    }

    public static IntPtr ArrayToIntptr(UInt16 [] source)
    {
        if (source == null)
        {
            return IntPtr.Zero;
        }

        unsafe
        {
            fixed (UInt16* point = source)
            {
                IntPtr ptr = new IntPtr(point);
                return ptr;
            }
        }
    }

    private void MouseLeftButtonDownEvent1(object sender, MouseButtonEventArgs e)
    {
        WPFImage1.CaptureMouse();
        originPos1 = e.GetPosition(border1);

        originPos2 = originPos1;
        originPos3 = originPos1;

        LeftBtnXpos.Show = originPos1.X.ToString();
        LeftBtnYpos.Show = originPos1.Y.ToString();

        if(e.ClickCount == 2)
        {
            double refPosX = originPos1.X * currentStretchRate;
            double refPosY = originPos1.Y * currentStretchRate;

            RectanglePos.X = imageStartX1 + refPosX;
            RectanglePos.Y = imageStartY1 + refPosY;
            RectangleWinPos = originPos1;
            Rectangle1.Stroke = System.Windows.Media.Brushes.Red;
            Rectangle2.Stroke = System.Windows.Media.Brushes.Red;
            Rectangle3.Stroke = System.Windows.Media.Brushes.Red;
            DrawRect(RectangleWinPos);
        }
    }

    private void MouseLeftButtonDownEvent2(object sender, MouseButtonEventArgs e)
    {
        WPFImage2.CaptureMouse();
        originPos2 = e.GetPosition(border2);

        originPos1 = originPos2;
        originPos3 = originPos2;
        if (e.ClickCount == 2)
        {
            //showRectangle = true;
            double refPosX = originPos2.X * currentStretchRate;
            double refPosY = originPos2.Y * currentStretchRate;

            RectanglePos.X = imageStartX2 + refPosX;
            RectanglePos.Y = imageStartY2 + refPosY;
            RectangleWinPos = originPos2;
            Rectangle1.Stroke = System.Windows.Media.Brushes.Red;
            Rectangle2.Stroke = System.Windows.Media.Brushes.Red;
            Rectangle3.Stroke = System.Windows.Media.Brushes.Red;
            DrawRect(RectangleWinPos);
        }
    }

    private void MouseLeftButtonDownEvent3(object sender, MouseButtonEventArgs e)
    {
        WPFImage3.CaptureMouse();
        originPos3 = e.GetPosition(border3);

        originPos1 = originPos3;
        originPos2 = originPos3;

        if (e.ClickCount == 2)
        {
            //showRectangle = true;
            double refPosX = originPos3.X * currentStretchRate;
            double refPosY = originPos3.Y * currentStretchRate;

            RectanglePos.X = imageStartX3 + refPosX;
            RectanglePos.Y = imageStartY3 + refPosY;
            RectangleWinPos = originPos3;
            Rectangle1.Stroke = System.Windows.Media.Brushes.Red;
            Rectangle2.Stroke = System.Windows.Media.Brushes.Red;
            Rectangle3.Stroke = System.Windows.Media.Brushes.Red;
            DrawRect(RectangleWinPos);
        }
    }

    private void MouseMoveEvent1(object sender, MouseEventArgs e)
    {
        if (WPFImage1.IsMouseCaptured)
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            dstPos1 = e.GetPosition(border1);

            //double currentStretchRate = imageShowSizeX1 / winWidth1;
            int panRangeX = (int)((dstPos1.X - originPos1.X)* currentStretchRate);
            int panRangeY = (int)((dstPos1.Y - originPos1.Y)* currentStretchRate);

            originPos1 = dstPos1;

            imageStartX1 -= panRangeX;
            imageStartY1 -= panRangeY;

            if (imageStartX1 < 0)
            {
                imageStartX1 = 0;
            }

            if (imageStartY1 < 0)
            {
                imageStartY1 = 0;
            }


            if (imageStartX1 > (nImgSizeX1 - imageShowSizeX1))
            {
                imageStartX1 = nImgSizeX1 - imageShowSizeX1;
            }
            if (imageStartY1 > (nImgSizeY1 - imageShowSizeY1))
            {
                imageStartY1 = nImgSizeY1 - imageShowSizeY1;
            }

            StartXpos.Show = imageStartX1.ToString();
            StartYpos.Show = imageStartY1.ToString();
            WidthSize.Show = imageShowSizeX1.ToString();
            HeightSize.Show = imageShowSizeY1.ToString();
            //CursorXpos.Show = currentPoint.X.ToString();
            //CursorYpos.Show = currentPoint.Y.ToString();
            if(ds2!=null)
            {
                imageStartX2 = imageStartX1;
                imageStartY2 = imageStartY1;
                imageShowSizeX2 = imageShowSizeX1;
                imageShowSizeY2 = imageShowSizeY1;
            }
            if (ds3 != null)
            {
                imageStartX3 = imageStartX1;
                imageStartY3 = imageStartY1;
                imageShowSizeX3 = imageShowSizeX1;
                imageShowSizeY3 = imageShowSizeY1;
            }

            ShowImg(imageStartX1, imageStartY1, imageShowSizeX1, imageShowSizeY1);             
        }
    }

    private void MouseMoveEvent2(object sender, MouseEventArgs e)
    {
        if (WPFImage2.IsMouseCaptured)
        {
            dstPos2 = e.GetPosition(border2);
            //double currentStretchRate = imageShowSizeX2 / winWidth2;
            int panRangeX = (int)((dstPos2.X - originPos2.X) * currentStretchRate);
            int panRangeY = (int)((dstPos2.Y - originPos2.Y) * currentStretchRate);

            originPos2 = dstPos2;

            imageStartX2 -= panRangeX;
            imageStartY2 -= panRangeY;

            if (imageStartX2 < 0)
            {
                imageStartX2 = 0;
            }
            if (imageStartY2 < 0)
            {
                imageStartY2 = 0;
            }
            if (imageStartX2 > (nImgSizeX2 - imageShowSizeX2))
            {
                imageStartX2 = nImgSizeX2 - imageShowSizeX2;
            }
            if (imageStartY2 > (nImgSizeY2 - imageShowSizeY2))
            {
                imageStartY2 = nImgSizeY2 - imageShowSizeY2;
            }



            //System.Windows.Point currentPoint = e.GetPosition(border);
            StartXpos.Show = imageStartX1.ToString();
            StartYpos.Show = imageStartY1.ToString();
            WidthSize.Show = imageShowSizeX1.ToString();
            HeightSize.Show = imageShowSizeY1.ToString();
            //CursorXpos.Show = currentPoint.X.ToString();
            //CursorYpos.Show = currentPoint.Y.ToString();

            if (ds1 != null)
            {
                imageStartX1 = imageStartX2;
                imageStartY1 = imageStartY2;
                imageShowSizeX1 = imageShowSizeX2;
                imageShowSizeY1 = imageShowSizeY2;
            }
            if (ds3 != null)
            {
                imageStartX3 = imageStartX2;
                imageStartY3 = imageStartY2;
                imageShowSizeX3 = imageShowSizeX2;
                imageShowSizeY3 = imageShowSizeY2;
            }

            ShowImg(imageStartX2, imageStartY2, imageShowSizeX2, imageShowSizeY2);
        }
    }

    private void MouseMoveEvent3(object sender, MouseEventArgs e)
    {
        if (WPFImage3.IsMouseCaptured)
        {
            dstPos3 = e.GetPosition(border3);
            //double currentStretchRate = imageShowSizeX2 / winWidth2;
            int panRangeX = (int)((dstPos3.X - originPos3.X) * currentStretchRate);
            int panRangeY = (int)((dstPos3.Y - originPos3.Y) * currentStretchRate);

            originPos3 = dstPos3;

            imageStartX3 -= panRangeX;
            imageStartY3 -= panRangeY;

            if (imageStartX3 < 0)
            {
                imageStartX3 = 0;
            }
            if (imageStartY3 < 0)
            {
                imageStartY3 = 0;
            }
            if (imageStartX3 > (nImgSizeX3 - imageShowSizeX3))
            {
                imageStartX3 = nImgSizeX3 - imageShowSizeX3;
            }
            if (imageStartY3 > (nImgSizeY3 - imageShowSizeY3))
            {
                imageStartY3 = nImgSizeY3 - imageShowSizeY3;
            }

            StartXpos.Show = imageStartX1.ToString();
            StartYpos.Show = imageStartY1.ToString();
            WidthSize.Show = imageShowSizeX1.ToString();
            HeightSize.Show = imageShowSizeY1.ToString();
            //CursorXpos.Show = currentPoint.X.ToString();
            //CursorYpos.Show = currentPoint.Y.ToString();

            if (ds1 != null)
            {
                imageStartX1 = imageStartX3;
                imageStartY1 = imageStartY3;
                imageShowSizeX1 = imageShowSizeX3;
                imageShowSizeY1 = imageShowSizeY3;
            }

            if (ds2 != null)
            {
                imageStartX2 = imageStartX3;
                imageStartY2 = imageStartY3;
                imageShowSizeX2 = imageShowSizeX3;
                imageShowSizeY2 = imageShowSizeY3;
            }

            ShowImg(imageStartX3, imageStartY3, imageShowSizeX3, imageShowSizeY3);
        }
    }


    private void MouseLeftButtonUpEvent1(object sender, MouseButtonEventArgs e)
    {
        WPFImage1.ReleaseMouseCapture();
    }

    private void MouseLeftButtonUpEvent2(object sender, MouseButtonEventArgs e)
    {
        WPFImage2.ReleaseMouseCapture();
    }

    private void MouseLeftButtonUpEvent3(object sender, MouseButtonEventArgs e)
    {
        WPFImage3.ReleaseMouseCapture();
    }

    private void MouseWheelEvent1(object sender, MouseWheelEventArgs e)
    {
        //int zoomTemp = e.Delta > 0 ? 1 : -1;
        //zoomValue += zoomTemp;
        //if(zoomValue < 1)
        //{
        //    zoomValue = 1;
        //}

        if (e.Delta > 0)
        {
            zoomValue *= 2;
        }
        else
        {
            zoomValue /= 2;
        }

        if (zoomValue < 1)
        {
            zoomValue = 1;
            return;
        }

        if (zoomValue > 64)
        {
            zoomValue = 64;
            return;
        }

        System.Windows.Point currentPoint = e.GetPosition(border1);

        currentStretchRate = (double)imageShowSizeX1 / (double)winWidth1;


        double refPosX = currentPoint.X * currentStretchRate;
        double refPosY = currentPoint.Y * currentStretchRate;
        double absPosX = 0;
        double absPosY = 0;
        absPosX = imageStartX1 + refPosX;
        absPosY = imageStartY1 + refPosY;

        imageShowSizeX1 = Convert.ToInt32((double)nImgSizeX1 / (double)(zoomValue));
        imageShowSizeY1 = Convert.ToInt32((double)nImgSizeY1 / (double)(zoomValue));

        currentStretchRate = (double)imageShowSizeX1 / (double)winWidth1;

        imageStartX1 = (int)(absPosX - currentPoint.X * currentStretchRate);
        imageStartY1 = (int)(absPosY - currentPoint.Y * currentStretchRate);

        if (imageStartX1 < 0)
        {
            imageStartX1 = 0;
        }
        if (imageStartY1 < 0)
        {
            imageStartY1 = 0;
        }
        if (imageStartX1 > (nImgSizeX1 - imageShowSizeX1))
        {
            imageStartX1 = nImgSizeX1 - imageShowSizeX1;
        }
        if (imageStartY1 > (nImgSizeY1 - imageShowSizeY1))
        {
            imageStartY1 = nImgSizeY1 - imageShowSizeY1;
        }

        //double currentStretchRate2 = (double)imageShowSizeX1 / (double)winWidth1;
        CursorXpos.Show = currentStretchRate.ToString();
        //UInt16[] pabyData = new UInt16[winWidth * winHight];

        //IntPtr pData = ArrayToIntptr(pabyData);
        StartXpos.Show = imageStartX1.ToString();
        StartYpos.Show = imageStartY1.ToString();
        WidthSize.Show = imageShowSizeX1.ToString();
        HeightSize.Show = imageShowSizeY1.ToString();
        CursorXpos.Show = currentPoint.X.ToString();
        //CursorYpos.Show = currentPoint.Y.ToString();

        if (ds2 != null)
        {
            imageStartX2 = imageStartX1;
            imageStartY2 = imageStartY1;
            imageShowSizeX2 = imageShowSizeX1;
            imageShowSizeY2 = imageShowSizeY1;
        }

        if (ds3 != null)
        {
            imageStartX3 = imageStartX1;
            imageStartY3 = imageStartY1;
            imageShowSizeX3 = imageShowSizeX1;
            imageShowSizeY3 = imageShowSizeY1;
        }

        ShowImg(imageStartX1, imageStartY1, imageShowSizeX1, imageShowSizeY1);
    }

    private void MouseWheelEvent2(object sender, MouseWheelEventArgs e)
    {

        if (e.Delta > 0)
        {
            zoomValue *= 2;
        }
        else
        {
            zoomValue /= 2;
        }

        if (zoomValue < 1)
        {
            zoomValue = 1;
            return;
        }

        if (zoomValue > 128)
        {
            zoomValue = 128;
            return;
        }


        System.Windows.Point currentPoint = e.GetPosition(border2);

        currentStretchRate = (double)imageShowSizeX2 / (double)winWidth2;

        double refPosX = currentPoint.X * currentStretchRate;
        double refPosY = currentPoint.Y * currentStretchRate;

        double absPosX = imageStartX2 + refPosX;
        double absPosY = imageStartY2 + refPosY;



        imageShowSizeX2 = Convert.ToInt32((double)nImgSizeX2 / (double)(zoomValue));
        imageShowSizeY2 = Convert.ToInt32((double)nImgSizeY2 / (double)(zoomValue));

        currentStretchRate = (double)imageShowSizeX2 / (double)winWidth2;

        imageStartX2 = (int)(absPosX - currentPoint.X * currentStretchRate);
        imageStartY2 = (int)(absPosY - currentPoint.Y * currentStretchRate);



        if (imageStartX2 < 0)
        {
            imageStartX2 = 0;
        }
        if (imageStartY2 < 0)
        {
            imageStartY2 = 0;
        }
        if (imageStartX2 > (nImgSizeX2 - imageShowSizeX2))
        {
            imageStartX2 = nImgSizeX2 - imageShowSizeX2;
        }
        if (imageStartY2 > (nImgSizeY2 - imageShowSizeY2))
        {
            imageStartY2 = nImgSizeY2 - imageShowSizeY2;
        }

        if (ds1 != null)
        {
            imageStartX1 = imageStartX2;
            imageStartY1 = imageStartY2;
            imageShowSizeX1 = imageShowSizeX2;
            imageShowSizeY1 = imageShowSizeY2;
        }

        if (ds3 != null)
        {
            imageStartX3 = imageStartX2;
            imageStartY3 = imageStartY2;
            imageShowSizeX3 = imageShowSizeX2;
            imageShowSizeY3 = imageShowSizeY2;
        }

        ShowImg(imageStartX2, imageStartY2, imageShowSizeX2, imageShowSizeY2);


    }

    private void MouseWheelEvent3(object sender, MouseWheelEventArgs e)
    {

        if (e.Delta > 0)
        {
            zoomValue *= 2;
        }
        else
        {
            zoomValue /= 2;
        }

        if (zoomValue < 1)
        {
            zoomValue = 1;
            return;
        }

        if (zoomValue > 128)
        {
            zoomValue = 128;
            return;
        }


        System.Windows.Point currentPoint = e.GetPosition(border3);

        currentStretchRate = (double)imageShowSizeX3 / (double)winWidth3;

        double refPosX = currentPoint.X * currentStretchRate;
        double refPosY = currentPoint.Y * currentStretchRate;

        double absPosX = imageStartX3 + refPosX;
        double absPosY = imageStartY3 + refPosY;



        imageShowSizeX3 = Convert.ToInt32((double)nImgSizeX3 / (double)(zoomValue));
        imageShowSizeY3 = Convert.ToInt32((double)nImgSizeY3 / (double)(zoomValue));

        currentStretchRate = (double)imageShowSizeX3 / (double)winWidth3;

        imageStartX3 = (int)(absPosX - currentPoint.X * currentStretchRate);
        imageStartY3 = (int)(absPosY - currentPoint.Y * currentStretchRate);



        if (imageStartX3 < 0)
        {
            imageStartX3 = 0;
        }
        if (imageStartY3 < 0)
        {
            imageStartY3 = 0;
        }
        if (imageStartX3 > (nImgSizeX3 - imageShowSizeX3))
        {
            imageStartX3 = nImgSizeX3 - imageShowSizeX3;
        }
        if (imageStartY3 > (nImgSizeY3 - imageShowSizeY3))
        {
            imageStartY3 = nImgSizeY3 - imageShowSizeY3;
        }

        if (ds1 != null)
        {
            imageStartX1 = imageStartX3;
            imageStartY1 = imageStartY3;
            imageShowSizeX1 = imageShowSizeX3;
            imageShowSizeY1 = imageShowSizeY3;
        }

        if (ds2 != null)
        {
            imageStartX2 = imageStartX3;
            imageStartY2 = imageStartY3;
            imageShowSizeX2 = imageShowSizeX3;
            imageShowSizeY2 = imageShowSizeY3;
        }

        ShowImg(imageStartX3, imageStartY3, imageShowSizeX3, imageShowSizeY3);
    }


        private void Button_Click(object sender, RoutedEventArgs e)
    {
        try
        {

            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.InitialDirectory = "G:\\N1\\Image";
            //dlg.Filter = "Image files (*.jpg)|*.jpg|All Files (*.*)|*.*";
            dlg.RestoreDirectory = true;

            if (dlg.ShowDialog() == true)
            {
                selectedFileName = dlg.FileName;
                ds1 = OSGeo.GDAL.Gdal.Open(selectedFileName, OSGeo.GDAL.Access.GA_ReadOnly);
                band1 = ds1.GetRasterBand(1);

                nImgSizeX1 = ds1.RasterXSize;
                nImgSizeY1 = ds1.RasterYSize;

                StretchRate = nImgSizeX1 / winWidth1;
                border1.Height = nImgSizeY1 / StretchRate;
                NavigationImg.Height = NavigationImg.Width * StretchRate;
                winHeight1 = (int)border1.Height;
                //winHeight = (int)border2.Height;

                imageStartX1 = 0;
                imageStartY1 = 0;
                imageShowSizeX1 = nImgSizeX1;
                imageShowSizeY1 = nImgSizeY1;
                zoomValue = 1;

                pabyData1 = new UInt16[winWidth1 * winHeight1];

                pData1 = ArrayToIntptr(pabyData1);

                band1.ReadRaster(imageStartX1, imageStartY1, imageShowSizeX1, imageShowSizeY1, pData1, winWidth1, winHeight1, OSGeo.GDAL.DataType.GDT_UInt16, 0, 0);
                var pixelFormat = PixelFormats.Gray16;
                var bytesPerPixel = (pixelFormat.BitsPerPixel + 7) / 8;
                var stride = bytesPerPixel * winWidth1;
                var bitmap = BitmapSource.Create(winWidth1, winHeight1, 72, 72,
                             pixelFormat, null, pabyData1, stride);

                WPFImage1.Source = bitmap;
                NavigationImg.Source = bitmap;
                //RectanglePos = null;
                Rectangle1.Stroke = System.Windows.Media.Brushes.Transparent;
                Rectangle2.Stroke = System.Windows.Media.Brushes.Transparent;
                Rectangle3.Stroke = System.Windows.Media.Brushes.Transparent;

            }
        }
        catch (Exception exp)
        {
            MessageBox.Show(exp.ToString());
            return;
        }
    }

    int zoomValue;
    string selectedFileName;
    System.Windows.Point originPos1;
    System.Windows.Point dstPos1;

    System.Windows.Point originPos2;
    System.Windows.Point dstPos2;

    System.Windows.Point originPos3;
    System.Windows.Point dstPos3;

    int imageStartX1;
    int imageStartY1;
    int imageShowSizeX1;
    int imageShowSizeY1;

    int imageStartX2;
    int imageStartY2;
    int imageShowSizeX2;
    int imageShowSizeY2;

    int imageStartX3;
    int imageStartY3;
    int imageShowSizeX3;
    int imageShowSizeY3;

    OSGeo.GDAL.Dataset ds1;
    OSGeo.GDAL.Dataset ds2;
    OSGeo.GDAL.Dataset ds3;

    OSGeo.GDAL.Band band1;
    OSGeo.GDAL.Band band2;
    OSGeo.GDAL.Band band3;

    UInt16[] pabyData1;
    UInt16[] pabyData2;
    UInt16[] pabyData3;

    int nImgSizeX1;
    int nImgSizeY1;
    int winWidth1;
    int winHeight1;

    int nImgSizeX2;
    int nImgSizeY2;
    int winWidth2;
    int winHeight2;

    int nImgSizeX3;
    int nImgSizeY3;
    int winWidth3;
    int winHeight3;

    IntPtr pData1;
    IntPtr pData2;
    IntPtr pData3;

    double StretchRate;
    MyTextshow StartXpos;
    MyTextshow StartYpos;
    MyTextshow WidthSize;
    MyTextshow HeightSize;
    MyTextshow CursorXpos;
    MyTextshow CursorYpos;
    MyTextshow LeftBtnXpos;
    MyTextshow LeftBtnYpos;

    double currentStretchRate;
    System.Windows.Point RectanglePos;
    System.Windows.Point RectangleWinPos;
    //bool showRectangle;
    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        try
        {

            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.InitialDirectory = "G:\\N1\\Image";
            //dlg.Filter = "Image files (*.jpg)|*.jpg|All Files (*.*)|*.*";
            dlg.RestoreDirectory = true;

            if (dlg.ShowDialog() == true)
            {
                selectedFileName = dlg.FileName;
                ds2 = OSGeo.GDAL.Gdal.Open(selectedFileName, OSGeo.GDAL.Access.GA_ReadOnly);
                band2 = ds2.GetRasterBand(1);

                nImgSizeX2 = ds2.RasterXSize;
                nImgSizeY2 = ds2.RasterYSize;

                StretchRate = nImgSizeX2 / winWidth2;
                border2.Height = nImgSizeY2 / StretchRate;
                winHeight2 = (int)border2.Height;
                //winHeight = (int)border2.Height;

                imageStartX2 = 0;
                imageStartY2 = 0;
                imageShowSizeX2 = nImgSizeX2;
                imageShowSizeY2 = nImgSizeY2;





                pabyData2 = new UInt16[winWidth2 * winHeight2];

                pData2 = ArrayToIntptr(pabyData2);

                band2.ReadRaster(imageStartX2, imageStartY2, imageShowSizeX2, imageShowSizeY2, pData2, winWidth2, winHeight2, OSGeo.GDAL.DataType.GDT_UInt16, 0, 0);

                var pixelFormat = PixelFormats.Gray16;
                var bytesPerPixel = (pixelFormat.BitsPerPixel + 7) / 8;
                var stride = bytesPerPixel * winWidth2;
                var bitmap = BitmapSource.Create(winWidth2, winHeight2, 72, 72,
                             pixelFormat, null, pabyData2, stride);

                WPFImage2.Source = bitmap;
                //showRectangle = false;
                Rectangle1.Stroke = System.Windows.Media.Brushes.Transparent;
                Rectangle2.Stroke = System.Windows.Media.Brushes.Transparent;
                Rectangle3.Stroke = System.Windows.Media.Brushes.Transparent;
            }
        }
        catch (Exception exp)
        {
            MessageBox.Show(exp.ToString());
            return;
        }
    }

    private void NavigationImg_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        NavigationImg.CaptureMouse();
        System.Windows.Point cursorPos = e.GetPosition(NavigationImg);
        double NavRate = (double)nImgSizeX1 / NavigationImg.Width;
        int absPosX = Convert.ToInt32(cursorPos.X * NavRate);
        int absPosY = Convert.ToInt32(cursorPos.Y * NavRate);

        RectanglePos.X = absPosX;
        RectanglePos.Y = absPosY;

        zoomValue = 32;
        imageShowSizeX1 = Convert.ToInt32((double)nImgSizeX1 / (double)(zoomValue));
        imageShowSizeY1 = Convert.ToInt32((double)nImgSizeY1 / (double)(zoomValue));
        currentStretchRate = (double)imageShowSizeX1 / (double)winWidth1;

        imageStartX1 = absPosX - imageShowSizeX1 / 2;
        imageStartY1 = absPosY - imageShowSizeY1 / 2;


        if (imageStartX1 < 0)
        {
            imageStartX1 = 0;
        }
        if (imageStartY1 < 0)
        {
            imageStartY1 = 0;
        }
        if (imageStartX1 > (nImgSizeX1 - imageShowSizeX1))
        {
            imageStartX1 = nImgSizeX1 - imageShowSizeX1;
        }
        if (imageStartY1 > (nImgSizeY1 - imageShowSizeY1))
        {
            imageStartY1 = nImgSizeY1 - imageShowSizeY1;
        }

        if (ds2 != null)
        {
            imageStartX2 = imageStartX1;
            imageStartY2 = imageStartY1;
            imageShowSizeX2 = imageShowSizeX1;
            imageShowSizeY2 = imageShowSizeY1;
        }

        if (ds2 != null)
        {
            imageStartX3 = imageStartX1;
            imageStartY3 = imageStartY1;
            imageShowSizeX3 = imageShowSizeX1;
            imageShowSizeY3 = imageShowSizeY1;
        }

        Rectangle1.Stroke = System.Windows.Media.Brushes.Red;
        Rectangle2.Stroke = System.Windows.Media.Brushes.Red;
        Rectangle3.Stroke = System.Windows.Media.Brushes.Red;
        ShowImg(imageStartX1, imageStartY1, imageShowSizeX1, imageShowSizeY1);
    }

    private void NavigationImg_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        NavigationImg.ReleaseMouseCapture();
    }

    private void Button_Click_2(object sender, RoutedEventArgs e)
    {
        try
        {

            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.InitialDirectory = "G:\\N1\\Image";
            //dlg.Filter = "Image files (*.jpg)|*.jpg|All Files (*.*)|*.*";
            dlg.RestoreDirectory = true;

            if (dlg.ShowDialog() == true)
            {
                selectedFileName = dlg.FileName;
                ds3 = OSGeo.GDAL.Gdal.Open(selectedFileName, OSGeo.GDAL.Access.GA_ReadOnly);
                band3 = ds3.GetRasterBand(1);

                nImgSizeX3 = ds3.RasterXSize;
                nImgSizeY3 = ds3.RasterYSize;

                StretchRate = nImgSizeX3 / winWidth3;
                border3.Height = nImgSizeY3 / StretchRate;
                winHeight3 = (int)border3.Height;
                //winHeight = (int)border2.Height;

                imageStartX3 = 0;
                imageStartY3 = 0;
                imageShowSizeX3 = nImgSizeX3;
                imageShowSizeY3 = nImgSizeY3;

                pabyData3 = new UInt16[winWidth3 * winHeight3];

                pData3 = ArrayToIntptr(pabyData3);

                band3.ReadRaster(imageStartX3, imageStartY3, imageShowSizeX3, imageShowSizeY3, pData3, winWidth3, winHeight3, OSGeo.GDAL.DataType.GDT_UInt16, 0, 0);

                var pixelFormat = PixelFormats.Gray16;
                var bytesPerPixel = (pixelFormat.BitsPerPixel + 7) / 8;
                var stride = bytesPerPixel * winWidth3;
                var bitmap = BitmapSource.Create(winWidth3, winHeight3, 72, 72,
                             pixelFormat, null, pabyData3, stride);

                WPFImage3.Source = bitmap;
                //showRectangle = false;
                Rectangle1.Stroke = System.Windows.Media.Brushes.Transparent;
                Rectangle2.Stroke = System.Windows.Media.Brushes.Transparent;
                Rectangle3.Stroke = System.Windows.Media.Brushes.Transparent;
            }
        }
        catch (Exception exp)
        {
            MessageBox.Show(exp.ToString());
            return;
        }
    }
}

class MyTextshow : INotifyPropertyChanged  
{
    private string show;
    public event PropertyChangedEventHandler PropertyChanged;
    public string Show
    {
        get { return show; }
        set
        {
            //show = value;
            //PropertyChanged(this, new PropertyChangedEventArgs("Show"));
            if (this.show != value)           
            {
                this.show = value;                                        
                if (PropertyChanged != null)                                    
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("Show"));
                }
            }
        }
    }
}

}