Ejemplo n.º 1
0
    private bool InsertFrames(bool after, double screenScale)
    {
        try
        {
            //Sizes.
            var left  = NewList[0].Path.SourceFrom();
            var right = CurrentList[0].Path.SourceFrom();

            //The image should be displayed based on the scale of the project.
            var scaleLeft  = left.DpiX / 96d;
            var scaleRight = right.DpiX / 96d; //Math.Round(right.DpiX / 96d, 2);

            var scaleDiffLeft  = screenScale / scaleLeft;
            var scaleDiffRight = screenScale / scaleRight;

            #region Current frames

            //If the canvas size changed.
            if (Math.Abs(RightCanvas.ActualWidth - _rightWidth) > 0.1 || Math.Abs(RightCanvas.ActualHeight - _rightHeight) > 0.1 ||
                Math.Abs(RightImage.ActualWidth - _rightWidth) > 0.1 || Math.Abs(RightImage.ActualHeight - _rightHeight) > 0.1)
            {
                StartProgress(CurrentList.Count, FindResource("S.Editor.UpdatingFrames").ToString());

                //Saves the state before resizing the images.
                ActionStack.SaveState(ActionStack.EditAction.ImageAndProperties, CurrentList, Util.Other.ListOfIndexes(0, CurrentList.Count));

                foreach (var frameInfo in CurrentList)
                {
                    #region Resize Images

                    //Draws the images into a DrawingVisual component.
                    var drawingVisual = new DrawingVisual();
                    using (var context = drawingVisual.RenderOpen())
                    {
                        //The back canvas.
                        context.DrawRectangle(new SolidColorBrush(UserSettings.All.InsertFillColor), null,
                                              new Rect(new Point(0, 0), new Point(Math.Round(RightCanvas.ActualWidth, MidpointRounding.AwayFromZero), Math.Round(RightCanvas.ActualHeight, MidpointRounding.AwayFromZero))));

                        var topPoint  = Dispatcher.Invoke <double>(() => Canvas.GetTop(RightImage)) * scaleDiffRight;
                        var leftPoint = Dispatcher.Invoke <double>(() => Canvas.GetLeft(RightImage)) * scaleDiffRight;

                        //The image.
                        context.DrawImage(frameInfo.Path.SourceFrom(), new Rect(leftPoint, topPoint, RightImage.ActualWidth * scaleDiffRight, RightImage.ActualHeight * scaleDiffRight));
                        //context.DrawText(new FormattedText("Hi!", CultureInfo.InvariantCulture, FlowDirection.LeftToRight, new Typeface("Segoe UI"), 32, Brushes.Black), new Point(0, 0));
                    }

                    //Converts the Visual (DrawingVisual) into a BitmapSource.
                    var bmp = new RenderTargetBitmap((int)Math.Round(RightCanvas.ActualWidth * screenScale, MidpointRounding.AwayFromZero),
                                                     (int)Math.Round(RightCanvas.ActualHeight * screenScale, MidpointRounding.AwayFromZero), right.DpiX, right.DpiX, PixelFormats.Pbgra32);
                    bmp.Render(drawingVisual);

                    #endregion

                    #region Save

                    //Creates a PngBitmapEncoder and adds the BitmapSource to the frames of the encoder
                    var encoder = new PngBitmapEncoder();
                    encoder.Frames.Add(BitmapFrame.Create(bmp));

                    //Saves the image into a file using the encoder
                    using (Stream stream = File.Create(frameInfo.Path))
                        encoder.Save(stream);

                    #endregion

                    if (_isCancelled)
                    {
                        return(false);
                    }

                    UpdateProgress(CurrentList.IndexOf(frameInfo));
                }
            }

            #endregion

            #region New frames

            StartProgress(CurrentList.Count, FindResource("S.Editor.ImportingFrames").ToString());

            var folder       = Path.GetDirectoryName(CurrentList[0].Path);
            var insertFolder = Path.GetDirectoryName(NewList[0].Path);

            //If the canvas size changed.
            if (Math.Abs(LeftCanvas.ActualWidth - _leftWidth) > 0.1 || Math.Abs(LeftCanvas.ActualHeight - _leftHeight) > 0.1 ||
                Math.Abs(LeftImage.ActualWidth - _leftWidth) > 0.1 || Math.Abs(LeftImage.ActualHeight - _leftHeight) > 0.1 || Math.Abs(left.DpiX - right.DpiX) > 0.1)
            {
                foreach (var frameInfo in NewList)
                {
                    #region Resize Images

                    //Draws the images into a DrawingVisual component.
                    var drawingVisual = new DrawingVisual();
                    using (var context = drawingVisual.RenderOpen())
                    {
                        //The back canvas.
                        context.DrawRectangle(new SolidColorBrush(UserSettings.All.InsertFillColor), null,
                                              new Rect(new Point(0, 0), new Point(Math.Round(RightCanvas.ActualWidth * scaleDiffRight, MidpointRounding.AwayFromZero),
                                                                                  Math.Round(RightCanvas.ActualHeight * scaleDiffRight, MidpointRounding.AwayFromZero))));

                        var topPoint  = Dispatcher.Invoke <double>(() => Canvas.GetTop(LeftImage)) * scaleDiffRight;
                        var leftPoint = Dispatcher.Invoke <double>(() => Canvas.GetLeft(LeftImage)) * scaleDiffRight;

                        //The front image.
                        context.DrawImage(frameInfo.Path.SourceFrom(), new Rect(leftPoint, topPoint, LeftImage.ActualWidth * scaleDiffRight, LeftImage.ActualHeight * scaleDiffRight)); // * scaleDiffLeft
                    }

                    //Converts the Visual (DrawingVisual) into a BitmapSource. Using the actual frame dpi.
                    var bmp = new RenderTargetBitmap((int)Math.Round(LeftCanvas.ActualWidth * screenScale, MidpointRounding.AwayFromZero),
                                                     (int)Math.Round(LeftCanvas.ActualHeight * screenScale, MidpointRounding.AwayFromZero), right.DpiX, right.DpiX, PixelFormats.Pbgra32);
                    bmp.Render(drawingVisual);

                    #endregion

                    #region Save

                    //Creates a PngBitmapEncoder and adds the BitmapSource to the frames of the encoder.
                    var encoder = new PngBitmapEncoder();
                    encoder.Frames.Add(BitmapFrame.Create(bmp));

                    File.Delete(frameInfo.Path);

                    var fileName = Path.Combine(folder, $"{_insertIndex}-{NewList.IndexOf(frameInfo)} {DateTime.Now:hh-mm-ss}.png");

                    //Saves the image into a file using the encoder.
                    using (Stream stream = File.Create(fileName))
                        encoder.Save(stream);

                    frameInfo.Path = fileName;

                    #endregion

                    if (_isCancelled)
                    {
                        return(false);
                    }

                    UpdateProgress(NewList.IndexOf(frameInfo));
                }
            }
            else
            {
                foreach (var frameInfo in NewList)
                {
                    #region Move

                    var fileName = Path.Combine(folder, $"{_insertIndex}-{NewList.IndexOf(frameInfo)} {DateTime.Now:hh-mm-ss}.png");

                    File.Move(frameInfo.Path, fileName);

                    frameInfo.Path = fileName;

                    #endregion

                    if (_isCancelled)
                    {
                        return(false);
                    }

                    UpdateProgress(NewList.IndexOf(frameInfo));
                }
            }

            Directory.Delete(insertFolder, true);

            #endregion

            if (_isCancelled)
            {
                return(false);
            }

            #region Merge the lists

            if (after)
            {
                _insertIndex++;
            }

            //Saves the state before inserting the images. This was removed because it was causing a crash when applying undo twice.
            //ActionStack.SaveState(ActionStack.EditAction.Add, _insertIndex, NewList.Count);

            CurrentList.InsertRange(_insertIndex, NewList);

            #endregion

            return(true);
        }
        catch (Exception ex)
        {
            LogWriter.Log(ex, "Insert Error");
            Dispatcher.Invoke(() => ErrorDialog.Ok("Insert Error", "Something Wrong Happened", ex.Message, ex));

            return(false);
        }
    }