Image edit exceptions

前端 未结 1 1125
深忆病人
深忆病人 2020-12-21 23:49

I\'m working in WPF application with MVVM. Loading and Editing a image in imageSlider gives me error and exceptions.

Loading Image: Insufficient memory to hand

1条回答
  •  萌比男神i
    2020-12-22 00:16

    You need to do things a little differently for an editor to a viewer

    your Model needs to be updated to a ViewModel as it will be changing ( you can use the model to build the ViewModel, however in this case there is so little functionality in the Model that you might as well use the FIleInfo class as your model)

    public class ImageEditor: IDisposable,INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        private List images = new List();
    
        private FileInfo _ImageFile;
        public static readonly PropertyChangedEventArgs FilenameProperty = new PropertyChangedEventArgs(nameof(ImageFile));
    
        public FileInfo ImageFile
        {
            get { return _ImageFile; }
            set
            {
                _ImageFile = value;
                Strokes.Clear();
                PropertyChanged?.Invoke(this, ImageFrameProperty);
            }
        }
    
        private int selectedIndex;
        public static readonly PropertyChangedEventArgs SelectedIndexProperty = new PropertyChangedEventArgs(nameof(SelectedIndex));
        public int SelectedIndex
        {
            get { return selectedIndex; }
            private set
            {
                if (value < images.Count && value > -1)
                {
                    selectedIndex = value;
                    PropertyChanged?.Invoke(this, SelectedIndexProperty);
                    ImageFile = images[selectedIndex];
                    Load();
                }
            }
        }
    
        MemoryStream mem;
        private BitmapSource _ImageFrame;
        public static readonly PropertyChangedEventArgs ImageFrameProperty = new PropertyChangedEventArgs(nameof(ImageFrame));
        public BitmapSource ImageFrame
        {
            get { return _ImageFrame; }
            set
            {
                _ImageFrame = value;
                PropertyChanged?.Invoke(this, ImageFrameProperty);
            }
        }
    
        public StrokeCollection Strokes { get;  } = new StrokeCollection();
    
        public void Open(FileInfo file)
        {
            images.Add(file);
            SelectedIndex = images.Count - 1;
        }
        public void Next()
        {
            SelectedIndex++;
        }
    
        public void Back()
        {
            SelectedIndex--;
        }
    
        public void Load()
        {
            ImageFile.Refresh();
            if (ImageFile.Exists)
            {
                if (mem != null)
                {
                    mem.Dispose();
                }
                using (var stream = ImageFile.OpenRead())
                {
                    mem = new MemoryStream();
                    stream.CopyTo(mem);
                }
                ImageFrame = BitmapFrame.Create(mem);
            }
        }
        public void Dispose()
        {
            if (mem != null)
            {
                mem.Dispose();
            }
            ImageFrame = null;
        }
    
        public void Save()
        {
    
            DrawingVisual drawingVisual = new DrawingVisual();
            using (DrawingContext drawingContext = drawingVisual.RenderOpen())
            {
    
                drawingContext.DrawImage(ImageFrame, new Rect(0, 0, ImageFrame.Width, ImageFrame.Height));
                foreach (var item in Strokes)
                {
                    item.Draw(drawingContext);
                }
                drawingContext.Close();
                Strokes.Clear();
                var width = ImageFrame.Width;
                var height = ImageFrame.Height;
                var bitmap = new RenderTargetBitmap((int)width, (int)height, 96, 96, PixelFormats.Pbgra32);
                bitmap.Render(drawingVisual);
    
                ImageFrame = bitmap;
    
                var encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(ImageFrame));
    
                using (var stream = ImageFile.OpenWrite())
                {
                    encoder.Save(stream);
                }
            }
        }
    }
    

    note: as we are using a memory stream with out the using statement then its a good idea to us the IDisposable interface for clean up

    what this is doing is creating a memory resident bitmap then using that as a Frame, this removes the openRead lock on on the file that you get with a normal bitmap with a URI

    next we have the Editor itself

    
        
            
    
        
    
        
            
                
                    
                    
                
                
                
                    White
                    Black
                    Yellow
                    Red
                    Cyan
                    SpringGreen
                    
                        
                            
                                
                                    
                                
                            
                        
                    
                
            
            

    Note if you are doing any scaling/stretching on the image then you need to reverse the operation on the Strokes before rendering them or or the edits will be in relation to the screen not the image

    0 讨论(0)
提交回复
热议问题