Loading

Win10 for Phone 裁剪控件

    <Page.BottomAppBar>
        <CommandBar x:Name="appBar">
            <AppBarButton Label="裁切" Icon="Crop" Click="AppBarButton_Crop_Click">
            </AppBarButton>
            <AppBarButton Label="完成" Icon="Accept" Click="AppBarButton_Accept_Click">
            </AppBarButton>
        </CommandBar>
    </Page.BottomAppBar>

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Image Name="CroppedImage"  
                Grid.Row="1"
                CacheMode="BitmapCache" ManipulationMode="All" 
                PointerPressed="CroppedImage_PointerPressed"
                PointerReleased="CroppedImage_PointerReleased"
                PointerMoved="CroppedImage_PointerMoved">
            <!--<Image.Clip>
                <RectangleGeometry x:Name="ClipRect"/>
            </Image.Clip>-->
        </Image>
        <Canvas Name="CropCanvas"
                 Grid.RowSpan="2">
            <Rectangle Name="LeftBack"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         Fill="#99000000"
                         IsHitTestVisible="False"/>
            <Rectangle Name="TopBack"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         Fill="#99000000"
                         IsHitTestVisible="False"/>
            <Rectangle Name="RightBack"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         Fill="#99000000"
                         IsHitTestVisible="False"/>
            <Rectangle Name="BottomBack"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         Fill="#99000000"
                         IsHitTestVisible="False"/>
            <TextBlock Name="SizeLabel"
                         Width="72"
                         TextAlignment="Right"
                         FontSize="14"
                         Foreground="Gray"
                         IsHitTestVisible="False"
                         FontFamily="{StaticResource PhoneFontFamilyNormal}"/>
            <Rectangle Name="TL"
                         Height="24"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         Width="24"
                         StrokeThickness="1"
                         Stroke="Transparent"
                         IsHitTestVisible="False"
                         Fill="Transparent"
                         Canvas.Left="{x:Bind PinTL.Left,Mode=OneWay}"
                         Canvas.Top="{x:Bind PinTL.Top,Mode=OneWay}"/>
            <Rectangle Name="TR"
                         Height="24"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         Width="24"
                         StrokeThickness="1"
                         Stroke="Transparent"
                         IsHitTestVisible="False"
                         Fill="Transparent"
                         Canvas.Left="{x:Bind PinTR.Left,Mode=OneWay}"
                         Canvas.Top="{x:Bind PinTR.Top,Mode=OneWay}"/>
            <Rectangle Name="BL"
                         Height="24"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         Width="24"
                         StrokeThickness="1"
                         Stroke="Transparent"
                         IsHitTestVisible="False"
                         Fill="Transparent"
                         Canvas.Left="{x:Bind PinBL.Left,Mode=OneWay}"
                         Canvas.Top="{x:Bind PinBL.Top,Mode=OneWay}"/>
            <Rectangle Name="BR"
                         Height="24"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         Width="24"
                         StrokeThickness="1"
                         Stroke="Transparent"
                         IsHitTestVisible="False"
                         Fill="Transparent"
                         Canvas.Left="{x:Bind PinBR.Left,Mode=OneWay}"
                         Canvas.Top="{x:Bind PinBR.Top,Mode=OneWay}"/>
        </Canvas>
    </Grid>
        #region 常量
        private Rectangle activePin;

        private const double doublePinSize = 48;

        private const double halfPinSize = 12;

        private bool isNew;

        private double minHeight;

        private double minWidth;

        private bool moveRect;

        private Point offset;

        private PinRect PinBL;

        private PinRect PinBR;

        private const double pinSize = 24;

        private PinRect PinTL;

        private PinRect PinTR;

        private int realHeight;

        private int realWidth;

        private double scale;

        private int startX;

        private int startY;

        private Point tapDiff;

        #endregion
        BitmapImage mSourceBitmap;
        public PhotoChooserPage()
        {
            this.InitializeComponent();

            SizeChangedEventHandler sizeChangedEventHandler = null;

            this.tapDiff = new Point(0, 0);
            this.scale = 1;
            this.minWidth = 1;
            this.minHeight = 1;
            this.PinTL = new PinRect();
            this.PinBL = new PinRect();
            this.PinTR = new PinRect();
            this.PinBR = new PinRect();
            this.TL.DataContext = this.PinTL;
            this.BL.DataContext = this.PinBL;
            this.TR.DataContext = this.PinTR;
            this.BR.DataContext = this.PinBR;
            Image croppedImage = this.CroppedImage;
            if (sizeChangedEventHandler == null)
            {
                sizeChangedEventHandler = (object s, SizeChangedEventArgs e) => this.InitImage();
            }
            croppedImage.SizeChanged += sizeChangedEventHandler;
            
        }
        private void InitImage()
        {
            if (this.isNew)
            {
                this.isNew = false;
                GeneralTransform visual = this.CroppedImage.TransformToVisual(Window.Current.Content);
                this.offset = visual.TransformPoint(new Point(0, 0));
                Size renderSize = this.CroppedImage.RenderSize;
                this.scale = renderSize.Width / (double)mSourceBitmap.PixelWidth;
                double num = this.scale * 100;
                ForUserInit();
            }
        }
        void ForUserInit()
        {
            this.minWidth = 100;
            this.minHeight = 100;

            Size renderSize = this.CroppedImage.RenderSize;
            double left = 0;
            double right = 0;

            if (renderSize.Width > 100)
                left = (renderSize.Width - 100) / 2;

            if (renderSize.Height > 100)
                right = (renderSize.Height - 100) / 2;

            double x = this.offset.X + left;
            double y = this.offset.Y + right;

            //左上角
            this.PinTL.RealLeft = x;
            this.PinTL.RealTop = y;

            //左下角
            this.PinBL.RealLeft = x;
            this.PinBL.RealTop = y + this.minHeight - 24;

            //右上角
            this.PinTR.RealLeft = x + this.minWidth - 24;
            this.PinTR.RealTop = y;

            //右下角
            this.PinBR.RealLeft = x + this.minWidth - 24;
            this.PinBR.RealTop = y + this.minHeight - 24;
            this.CroppedImage_PointerMoved(null, null);
        }


        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (e.NavigationMode == NavigationMode.New)
            {
                // 如果用户选择了图片,则显示在屏幕上
                mSourceBitmap = e.Parameter as BitmapImage;
                //CroppedImage
                CroppedImage.Source = mSourceBitmap;
                isNew = true;
            }
        }

        private void CroppedImage_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            Point position = e.GetCurrentPoint(this.CroppedImage).Position;
            this.activePin = null;
            this.moveRect = false;
            if (this.IsRectTapped(position.X + this.offset.X, position.Y + this.offset.Y))
            {
                this.moveRect = true;
            }
            if (this.IsPinTapped(this.PinTL, position.X + this.offset.X, position.Y + this.offset.Y))
            {
                this.activePin = this.TL;
            }
            if (this.IsPinTapped(this.PinTR, position.X + this.offset.X, position.Y + this.offset.Y))
            {
                this.activePin = this.TR;
            }
            if (this.IsPinTapped(this.PinBL, position.X + this.offset.X, position.Y + this.offset.Y))
            {
                this.activePin = this.BL;
            }
            if (this.IsPinTapped(this.PinBR, position.X + this.offset.X, position.Y + this.offset.Y))
            {
                this.activePin = this.BR;
            }
        }

        private void CroppedImage_PointerReleased(object sender, PointerRoutedEventArgs e)
        {
            this.moveRect = false;
            this.activePin = null;
        }

        private void CroppedImage_PointerMoved(object sender, PointerRoutedEventArgs e)
        {
            Point position;
            if (e != null)
            {
                position = e.GetCurrentPoint(this.CroppedImage).Position;
            }
            else
            {
                Point point = new Point();
                position = point;
            }
            Point point1 = position;
            double x = point1.X + this.offset.X + this.tapDiff.X;
            double y = point1.Y + this.offset.Y + this.tapDiff.Y;
            double realLeft = this.PinBR.RealLeft - this.PinTL.RealLeft;
            double realTop = this.PinBR.RealTop - this.PinTL.RealTop;

            if (this.activePin == null)
            {
                if (this.moveRect)
                {
                    if (x < this.offset.X)
                    {
                        x = this.offset.X;
                    }
                    Size renderSize = this.CroppedImage.RenderSize;
                    if (x > this.offset.X + renderSize.Width - realLeft - 24)
                    {
                        Size size = this.CroppedImage.RenderSize;
                        x = this.offset.X + size.Width - realLeft - 24;
                    }
                    if (y < this.offset.Y)
                    {
                        y = this.offset.Y;
                    }
                    Size renderSize1 = this.CroppedImage.RenderSize;
                    if (y > this.offset.Y + renderSize1.Height - realTop - 24)
                    {
                        Size size1 = this.CroppedImage.RenderSize;
                        y = this.offset.Y + size1.Height - realTop - 24;
                    }
                    this.PinTL.RealLeft = x;
                    this.PinTL.RealTop = y;
                    this.PinBL.RealLeft = x;
                    this.PinBL.RealTop = y + realTop;
                    this.PinBR.RealLeft = x + realLeft;
                    this.PinBR.RealTop = y + realTop;
                    this.PinTR.RealLeft = x + realLeft;
                    this.PinTR.RealTop = y;
                }
            }
            else
                this.MoveInRatio(x, 1);

            Point imageSize = this.GetImageSize();
            this.LeftBack.SetValue(Canvas.LeftProperty, this.offset.X);
            this.LeftBack.SetValue(Canvas.TopProperty, this.offset.Y);
            this.LeftBack.Height = Math.Max(0, Math.Ceiling(imageSize.Y));
            this.LeftBack.Width = Math.Max(0, (double)this.PinTL.Left - this.offset.X);

            this.RightBack.SetValue(Canvas.LeftProperty, (double)this.PinBR.Left + 24);
            this.RightBack.SetValue(Canvas.TopProperty, this.offset.Y);
            this.RightBack.Height = Math.Max(0, Math.Ceiling(imageSize.Y));
            this.RightBack.Width = Math.Max(0, Math.Ceiling(imageSize.X) + this.offset.X - 24 - (double)this.PinBR.Left);

            this.TopBack.SetValue(Canvas.LeftProperty, (double)this.PinTL.Left);
            this.TopBack.SetValue(Canvas.TopProperty, this.offset.Y);
            this.TopBack.Height = Math.Max(0, (double)this.PinTL.Top - this.offset.Y);
            this.TopBack.Width = Math.Max(0, (double)(this.PinBR.Left - this.PinTL.Left) + 24);

            this.BottomBack.SetValue(Canvas.LeftProperty, (double)this.PinTL.Left);
            this.BottomBack.SetValue(Canvas.TopProperty, (double)this.PinBR.Top + 24);
            this.BottomBack.Height = Math.Max(0, Math.Ceiling(imageSize.Y) + this.offset.Y - 24 - (double)this.PinBR.Top);
            this.BottomBack.Width = Math.Max(0, (double)(this.PinBR.Left - this.PinTL.Left) + 24);

            realLeft = this.PinBR.RealLeft - this.PinTL.RealLeft;
            realTop = this.PinBR.RealTop - this.PinTL.RealTop;

            this.startX = (int)Math.Round((this.PinTL.RealLeft - this.offset.X) / this.scale);
            this.startY = (int)Math.Round((this.PinTL.RealTop - this.offset.Y) / this.scale);
            this.realWidth = (int)Math.Round((realLeft + 24) / this.scale);
            this.realHeight = (int)Math.Round((realTop + 24) / this.scale);
        }
        private Point GetImageSize()
        {
            Size renderSize = this.CroppedImage.RenderSize;
            if (renderSize.Height == 0)
            {
                Size size = this.CroppedImage.RenderSize;
                if (size.Width == 0)
                {
                    return new Point(this.CroppedImage.ActualWidth, this.CroppedImage.ActualHeight);
                }
            }
            Size renderSize1 = this.CroppedImage.RenderSize;
            Size size1 = this.CroppedImage.RenderSize;
            return new Point(renderSize1.Width, size1.Height);
        }
        private bool IsPinTapped(PinRect pin, double left, double top)
        {
            bool flag;
            if (left < pin.RealLeft - 12 || left > pin.RealLeft + 36 || top < pin.RealTop - 12)
            {
                flag = false;
            }
            else
            {
                flag = top <= pin.RealTop + 36;
            }
            bool flag1 = flag;
            if (flag1)
            {
                this.tapDiff = new Point(pin.RealLeft - left, pin.RealTop - top);
            }
            return flag1;
        }
        private bool IsRectTapped(double left, double top)
        {
            Rect rect = new Rect(this.PinTL.RealLeft, this.PinTL.RealTop, this.PinBR.RealLeft + 24, this.PinBR.RealTop + 24);
            bool flag = rect.Contains(new Point(left, top));
            if (flag)
            {
                this.tapDiff = new Point(this.PinTL.RealLeft - left, this.PinTL.RealTop - top);
            }
            return flag;
        }
        private void MoveInRatio(double y, double rate)
        {
            if (this.activePin.Equals(this.BR))
            {
                double x = y;
                double realLeft = (x + 24 - this.PinTL.RealLeft) / rate + this.PinTL.RealTop - 24;
                Size renderSize = this.CroppedImage.RenderSize;
                if (x > this.offset.X + renderSize.Width - 24)
                {
                    Size size = this.CroppedImage.RenderSize;
                    x = this.offset.X + size.Width - 24;
                    realLeft = (x + 24 - this.PinTL.RealLeft) / rate + this.PinTL.RealTop - 24;
                }
                Size renderSize1 = this.CroppedImage.RenderSize;
                if (realLeft > this.offset.Y + renderSize1.Height - 24)
                {
                    Size size1 = this.CroppedImage.RenderSize;
                    realLeft = this.offset.Y + size1.Height - 24;
                    x = (realLeft + 24 - this.PinTL.RealTop) * rate + this.PinTL.RealLeft - 24;
                }
                if (x < this.PinTL.RealLeft + this.minWidth - 24)
                {
                    x = this.PinTL.RealLeft + this.minWidth - 24;
                    realLeft = this.PinTL.RealTop + this.minHeight - 24;
                }
                this.PinTR.RealLeft = x;
                this.PinBL.RealTop = realLeft;
                this.PinBR.RealLeft = x;
                this.PinBR.RealTop = realLeft;
            }
            if (this.activePin.Equals(this.TR))
            {
                double realTop = y;
                double num = this.PinBL.RealTop - (realTop + 24 - this.PinBL.RealLeft) / rate + 24;
                Size renderSize2 = this.CroppedImage.RenderSize;
                if (realTop > this.offset.X + renderSize2.Width - 24)
                {
                    Size size2 = this.CroppedImage.RenderSize;
                    realTop = this.offset.X + size2.Width - 24;
                    num = this.PinBL.RealTop - (realTop + 24 - this.PinBL.RealLeft) / rate + 24;
                }
                if (num < this.offset.Y)
                {
                    num = this.offset.Y;
                    realTop = (this.PinBL.RealTop - num + 24) * rate + this.PinBL.RealLeft - 24;
                }
                if (realTop < this.PinBL.RealLeft + this.minWidth - 24)
                {
                    realTop = this.PinBL.RealLeft + this.minWidth - 24;
                    num = this.PinBL.RealTop - this.minHeight + 24;
                }
                this.PinBR.RealLeft = realTop;
                this.PinTL.RealTop = num;
                this.PinTR.RealLeft = realTop;
                this.PinTR.RealTop = num;
            }
            if (this.activePin.Equals(this.TL))
            {
                double realLeft1 = y;
                double realTop1 = this.PinBR.RealTop - (this.PinBR.RealLeft + 24 - realLeft1) / rate + 24;
                if (realLeft1 > this.PinBR.RealLeft + 24 - this.minWidth)
                {
                    realLeft1 = this.PinBR.RealLeft + 24 - this.minWidth;
                    realTop1 = this.PinBR.RealTop + 24 - this.minHeight;
                }
                if (realTop1 < this.offset.Y)
                {
                    realTop1 = this.offset.Y;
                    realLeft1 = this.PinBR.RealLeft + 24 - (this.PinBR.RealTop - realTop1 + 24) * rate;
                }
                if (realLeft1 < this.offset.X)
                {
                    realLeft1 = this.offset.X;
                    realTop1 = this.PinBR.RealTop - (this.PinBR.RealLeft + 24 - realLeft1) / rate + 24;
                }
                this.PinBL.RealLeft = realLeft1;
                this.PinTR.RealTop = realTop1;
                this.PinTL.RealLeft = realLeft1;
                this.PinTL.RealTop = realTop1;
            }
            if (this.activePin.Equals(this.BL))
            {
                double x1 = y;
                double num1 = (this.PinTR.RealLeft + 24 - x1) / rate + this.PinTR.RealTop - 24;
                if (x1 > this.PinTR.RealLeft + 24 - this.minWidth)
                {
                    x1 = this.PinTR.RealLeft + 24 - this.minWidth;
                    num1 = this.PinTR.RealTop + this.minHeight - 24;
                }
                Size renderSize3 = this.CroppedImage.RenderSize;
                if (num1 > this.offset.Y + renderSize3.Height - 24)
                {
                    Size size3 = this.CroppedImage.RenderSize;
                    num1 = this.offset.Y + size3.Height - 24;
                    x1 = this.PinTR.RealLeft - (num1 + 24 - this.PinTR.RealTop) * rate + 24;
                }
                if (x1 < this.offset.X)
                {
                    x1 = this.offset.X;
                    num1 = (this.PinTR.RealLeft + 24 - x1) / rate + this.PinTR.RealTop - 24;
                }
                this.PinTL.RealLeft = x1;
                this.PinBR.RealTop = num1;
                this.PinBL.RealLeft = x1;
                this.PinBL.RealTop = num1;
            }
        }
        public static WriteableBitmap writeableBmp;
        private async void AppBarButton_Crop_Click(object sender, RoutedEventArgs e)
        {


        }

        private void AppBarButton_Accept_Click(object sender, RoutedEventArgs e)
        {

        }

 

posted @ 2015-06-02 18:50  androllen  阅读(284)  评论(0编辑  收藏  举报