Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF/C#在ValueChanged事件中更新(和处理)位图/位图源?_C#_Wpf - Fatal编程技术网

WPF/C#在ValueChanged事件中更新(和处理)位图/位图源?

WPF/C#在ValueChanged事件中更新(和处理)位图/位图源?,c#,wpf,C#,Wpf,我有一个小的图像编辑程序,它可以打开一个图像,并对它做一些有趣的事情。在本例中,我尝试调整像素的亮度。问题在于像素设置不正确,而是处理在“我的滑块”的ValueChanged事件中创建的位图/位图源 因此,基本上用户将单击一个按钮,它将打开一个带有滑块的新窗口。此新窗口将复制原始位图供以后使用 当滑块的值更改时,它将从原始位图创建一个具有相应亮度增加的新位图,从该位图创建一个新位图源,并更新图像控件的源。即使我使用的是“using”语句,但在滑动这么长时间后,我仍然会出现“内存不足”异常 知道为

我有一个小的图像编辑程序,它可以打开一个图像,并对它做一些有趣的事情。在本例中,我尝试调整像素的亮度。问题在于像素设置不正确,而是处理在“我的滑块”的ValueChanged事件中创建的位图/位图源

因此,基本上用户将单击一个按钮,它将打开一个带有滑块的新窗口。此新窗口将复制原始位图供以后使用

当滑块的值更改时,它将从原始位图创建一个具有相应亮度增加的新位图,从该位图创建一个新位图源,并更新图像控件的源。即使我使用的是“using”语句,但在滑动这么长时间后,我仍然会出现“内存不足”异常

知道为什么吗?是否有更好的解决方法可以实现同样的目标?我已包括以下代码:

using Imagin.Slideshow;
using System;
using System.Collections.Generic;
using System.Drawing;
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.Shapes;

namespace Imagin
{
    /// <summary>
    /// Interaction logic for BrightnessWindow.xaml
    /// </summary>
    public partial class BrightnessWindow : Window
    {

        public int Increase;

        private System.Drawing.Bitmap Bitmap;
        private System.Drawing.Bitmap NewBitmap;

        private MainWindow ParentWindow;

        public BrightnessWindow(MainWindow m)
        {

            InitializeComponent();

            this.ParentWindow = m;

            this.Bitmap = (System.Drawing.Bitmap)this.ParentWindow.Document.Bitmap.Clone();

        }

        private void slider1_ValueChanged(object sender, RoutedEventArgs e) 
        {

            using (System.Drawing.Bitmap b = (System.Drawing.Bitmap)this.ParentWindow.Document.Bitmap.Clone(new RectangleF() { Width = (int)this.ParentWindow.Document.Bitmap.Width, Height = (int)this.ParentWindow.Document.Bitmap.Height, X = 0, Y = 0 }, this.ParentWindow.Document.Bitmap.PixelFormat))
            {
                this.ParentWindow.SetPixels(b, AdjustmentTypes.Brightness, Convert.ToInt32(this.slider1.Value));
                BitmapSource m = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(b.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                this.ParentWindow.image1.Source = m;
                this.NewBitmap = (System.Drawing.Bitmap)b.Clone();
            }

        }

        private void applyButton_Click(object sender, RoutedEventArgs e)
        {
            if (this.NewBitmap != null)
            {
                this.ParentWindow.Document.Bitmap = this.NewBitmap;
            }
            this.Close();
        }

        private void cancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.ParentWindow.Document.Refresh();

            this.Close();
        }
    }
}
使用Imagin.Slideshow;
使用制度;
使用System.Collections.Generic;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Shapes;
名称空间想象
{
/// 
///BrightnessWindow.xaml的交互逻辑
/// 
公共部分类BrightnessWindow:窗口
{
公共收入增加;
私有System.Drawing.Bitmap位图;
私有System.Drawing.Bitmap NewBitmap;
私有主窗口父窗口;
公共亮度窗口(主窗口m)
{
初始化组件();
this.ParentWindow=m;
this.Bitmap=(System.Drawing.Bitmap)this.ParentWindow.Document.Bitmap.Clone();
}
私有无效滑块1_值已更改(对象发送方,路由目标e)
{
使用(System.Drawing.Bitmap b=(System.Drawing.Bitmap)this.ParentWindow.Document.Bitmap.Clone(新矩形F(){Width=(int)this.ParentWindow.Document.Bitmap.Width,Height=(int)this.ParentWindow.Document.Bitmap.Height,X=0,Y=0},this.ParentWindow.Document.Bitmap.PixelFormat))
{
this.ParentWindow.SetPixels(b,AdjustmentTypes.Brightness,Convert.ToInt32(this.slider1.Value));
BitmapSource m=System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(b.GetHbitmap()、IntPtr.Zero、Int32Rect.Empty、BitmapSizeOptions.FromEmptyOptions());
this.ParentWindow.image1.Source=m;
this.NewBitmap=(System.Drawing.Bitmap)b.Clone();
}
}
私有无效应用程序按钮单击(对象发送器,路由EventTarget e)
{
如果(this.NewBitmap!=null)
{
this.ParentWindow.Document.Bitmap=this.NewBitmap;
}
这个。关闭();
}
私有作废取消按钮\u单击(对象发送方,路由目标)
{
此文件为.ParentWindow.Document.Refresh();
这个。关闭();
}
}
}
我想知道的另一件事是,是否有更好的方法来更改主窗口的控件,而不必将其作为参数传递,或者这是此类事情的首选方法?谢谢

每次使用bitmap.GetHbitmap时,都会创建一个gdibitmap的新实例。根据msdn链接,“您负责调用GDI DeleteObject方法以释放GDI位图对象使用的内存。有关GDI位图的更多信息,请参阅Windows GDI文档中的位图。”

我会把那个家伙拉到一个变量上,在处理完它后调用deleteobject,否则你只会创建
n
gdibitmap,其中
n
=
移动滑块的次数
,并且永远不会处理它们

编辑:高亮显示行:

//Somewhere in the class
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

    private void slider1_ValueChanged(object sender, RoutedEventArgs e) 
    {

        using (System.Drawing.Bitmap b = (System.Drawing.Bitmap)this.ParentWindow.Document.Bitmap.Clone(new RectangleF() { Width = (int)this.ParentWindow.Document.Bitmap.Width, Height = (int)this.ParentWindow.Document.Bitmap.Height, X = 0, Y = 0 }, this.ParentWindow.Document.Bitmap.PixelFormat))
        {
            this.ParentWindow.SetPixels(b, AdjustmentTypes.Brightness, Convert.ToInt32(this.slider1.Value));
            IntPtr hbitmap = b.GetHbitmap(); //create variable so we don't orphan the object
            BitmapSource m = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hbitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); //use variable
            this.ParentWindow.image1.Source = m;
            this.NewBitmap = (System.Drawing.Bitmap)b.Clone();
            DeleteObject(hbitmap); //delete gdi object
        }

    }

所以我发现没有这一行导致了我们的问题:
如果(this.NewBitmap!=null){this.NewBitmap.Dispose();}
但是,现在我得到了错误“System.Drawing.dll中发生“System.Runtime.InteropServices.ExternalException”类型的异常,但未在用户代码中处理;其他信息:GDI+中出现一般性错误。“从以下行:
BitmapSource m=System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(b.GetHbitmap()、IntPtr.Zero、Int32Rect.Empty、BitmapSizeOptions.FromEmptyOptions())
在将新位图源或位图设置为任何内容之前,请先尝试处置原始位图。我看到您不使用任何BrightnessWindow::Bitmap字段。很好,我是对的。:)但是第二个错误呢?它不是很明确:/在调试菜单下,选择“异常”,并在弹出的对话框中,在“抛出”列中为“公共语言运行时异常”放置一个复选框。单击“确定”,然后再次尝试调试。在研究您的答案后,我发现:,这有助于我正确处理对象。编译器无法识别DeleteObject方法,所以希望这能帮助遇到相同问题的其他人。谢谢