标签: bitmapsource

为什么BitmapSource.Create会抛出ArgumentException?

我试图通过使用Image和BitmapSource从WPF中显示原始数据创建的位图:

Int32[] data = new Int32[RenderHeight * RenderWidth];

for (Int32 i = 0; i < RenderHeight; i++)
{
    for (Int32 j = 0; j < RenderWidth; j++)
    {
        Int32 index = j + (i * RenderHeight);

        if (i + j % 2 == 0)
            data[index] = 0xFF0000;
        else
            data[index] = 0x00FF00;
    }
}

BitmapSource source = BitmapSource.Create(RenderWidth, RenderHeight, 96.0, 96.0, PixelFormats.Bgr32, null, data, 0);

RenderImage.Source = source;
Run Code Online (Sandbox Code Playgroud)

但是,对BitmapSource.Create的调用会抛出ArgumentException,并说"值不在预期范围内".这不是这样做的方法吗?我没有正确地打电话吗?

c# bitmapsource stride

7
推荐指数
1
解决办法
7853
查看次数

如何从Brush(例如DrawingBrush)转换为BitmapSource?

我有一个带有一些矢量图形的DrawingBrush.我想将它转换为BitmapSource作为将其转换为Bitmap的中间步骤.最好的方法是什么?

wpf bitmapsource drawingbrush

6
推荐指数
1
解决办法
2422
查看次数

DPI在BitmapSource.Create()方法中的相关性是什么?

我阅读了有关DPI的维基百科文章,但它让我更加困惑......我没有关于图像的任何DPI信息.我应该使用什么DPI与BitmapSource.Create(),使用常量(96/72?)是否可以,如果我不打算打印图像真的很重要吗?

c# wpf bitmapsource dpi

6
推荐指数
1
解决办法
1825
查看次数

WPF/BackgroundWorker和BitmapSource问题

我是WPF的初学者,并尝试了一个熟悉该技术的家庭项目.我有一个简单的表单,用户选择一个图像文件,然后我显示EXIF数据和图像的缩略图.这工作正常但是当我选择一个RAW图像文件(~9 MB)时,拇指加载时可能会有轻微的延迟,所以我想我可以使用BackgroundWorker解码图像,用户可以查看EXIF数据,然后当图像被解码时,显示它.

BitmapSource对象在BackgroundWorkers DoWork方法中声明:

worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
    string filePath = args.Argument as string;

    BitmapDecoder bmpDecoder = BitmapDecoder.Create(new Uri(filePath), BitmapCreateOptions.None, BitmapCacheOption.None);
    BitmapSource bmpSource = bmpDecoder.Frames[0];
    bmpSource.Freeze(); //As suggested by Paul Betts

    args.Result = bmpSource;
};
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是当我尝试在RunWorkerCompleted方法中设置我的Image控件的源时,我收到一个错误,因为该对象归另一个线程所有.

worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
    imgThumb.Source = args.Result as BitmapSource;
};
Run Code Online (Sandbox Code Playgroud)

我尝试使用该imgThumb.Dispatcher.BeginInvoke()方法设置源,但这也不起作用,我想这是因为它args.Result是由另一个线程拥有,而不是imgThumb?我怎么能绕过这个?

可能是我对我的调度程序编码错误(以下内容来自内存,我删除了我的内容).

imgThumb.Dispatcher.Invoke(new Action<BitmapSource>(
    delegate(BitmapSource src)
    {
        imgThumb.Source = src;
    }
), bmpSource);
Run Code Online (Sandbox Code Playgroud)

欢迎任何建议或想法.

更新

更改了我的DoWork方法以使用BitmapCreateOptions.None而不是.DelayCreation但现在我在加载RAW文件时遇到以下错误(Canon .CR2文件是我迄今为止测试的所有文件),代码适用于jpg.这可能是我安装的Canon Codec的一个问题,允许我显示RAW文件?

该应用程序调用了一个为不同线程编组的接口.(来自HRESULT的异常:0x8001010E(RPC_E_WRONG_THREAD))

wpf bitmapsource backgroundworker

5
推荐指数
1
解决办法
2676
查看次数

InteropBitmap到BitmapImage

我正在尝试将a转换Bitmap (SystemIcons.Question)为a,BitmapImage因此我可以在WPF图像控件中使用它.

我有以下方法将其转换为a BitmapSource,但它返回一个InteropBitmapImage,现在的问题是如何将其转换为BitmapImage.直接演员似乎不起作用.

有谁知道怎么做?

码:

 public BitmapSource ConvertToBitmapSource()
        {
            int width = SystemIcons.Question.Width;
            int height = SystemIcons.Question.Height;
            object a = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(SystemIcons.Question.ToBitmap().GetHbitmap(), IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight(width, height));

            return (BitmapSource)a;
        }
Run Code Online (Sandbox Code Playgroud)

返回BitmapImage的属性:(绑定到我的图像控件)

public BitmapImage QuestionIcon
        {
            get
            {
                return  (BitmapImage)ConvertToBitmapSource();
            }
        }
Run Code Online (Sandbox Code Playgroud)

c# wpf bitmapsource bitmapimage interopbitmapimage

5
推荐指数
1
解决办法
8559
查看次数

如何将DispatcherObject(BitmapSource)复制到不同的线程?

我试图弄清楚如何将DispatcherObject(在我的案例中为BitmapSource)复制到另一个线程中.

使用案例:
我有一个需要在新线程中显示窗口的WPF应用程序(该应用程序实际上是Outlook插件,我们需要这样做,因为Outlook在主UI线程中有一些钩子并且正在窃取我们需要使用的某些热键 - 在Outlook,WPF(我们用于UI)和Winforms(我们需要使用某些微软提供的winforms控件)的互操作中"丢失翻译").

有了这个,我有WPFMessageBox的实现,通过设置一些静态属性来配置 - 其中一个是图标的BitmapSource.这样使用,以便在启动时我可以设置一次WPFMessageBox.Icon,从那时起,每个WPFMessageBox将具有相同的图标.

问题是分配给图标的BitmapSource是DispatcherObject,当读取时,它将抛出InvalidOperationException:"调用线程无法访问此对象,因为不同的线程拥有它.".

如何将BitmapSource克隆到实际线程中?它有Clone()和CloneCurrentValue()方法,它们不起作用(它们也抛出相同的异常).我也发现使用originalIcon.Dispatcher.Invoke(在这里进行克隆) - 但BitmapSource的Dispatcher为null,仍然 - 我在错误的线程上创建了一个副本,但仍然无法在我的上使用它.BitmapSource.IsFrozen == true.

关于如何将BitmapSource复制到不同的线程(没有从新线程中的图像文件完全重构)的任何想法?

编辑: 所以,冻结没有帮助:最后我有一个BitmapFrame(Window.Icon无论如何也不会采用任何其他类型的ImageSource),当我在另一个线程上将其指定为Window.Icon时,即使冻结,我得到InvalidOperationException:"调用线程无法访问此对象,因为另一个线程拥有它." 具有以下堆栈跟踪:

    WindowsBase.dll!System.Windows.Threading.Dispatcher.VerifyAccess() + 0x4a bytes 
    WindowsBase.dll!System.Windows.Threading.DispatcherObject.VerifyAccess() + 0xc bytes    
    PresentationCore.dll!System.Windows.Media.Imaging.BitmapDecoder.Frames.get() + 0xe bytes    
    PresentationFramework.dll!MS.Internal.AppModel.IconHelper.GetIconHandlesFromBitmapFrame(object callingObj = {WPFControls.WPFMBox.WpfMessageBoxWindow: header}, System.Windows.Media.Imaging.BitmapFrame bf = {System.Windows.Media.Imaging.BitmapFrameDecode}, ref MS.Win32.NativeMethods.IconHandle largeIconHandle = {MS.Win32.NativeMethods.IconHandle}, ref MS.Win32.NativeMethods.IconHandle smallIconHandle = {MS.Win32.NativeMethods.IconHandle}) + 0x3b bytes   
>   PresentationFramework.dll!System.Windows.Window.UpdateIcon() + 0x118 bytes  
    PresentationFramework.dll!System.Windows.Window.SetupInitialState(double requestedTop = NaN, double requestedLeft = NaN, double requestedWidth = 560.0, double requestedHeight = NaN) + 0x8a bytes  
    PresentationFramework.dll!System.Windows.Window.CreateSourceWindowImpl() + …
Run Code Online (Sandbox Code Playgroud)

.net c# wpf exception-handling bitmapsource

5
推荐指数
3
解决办法
4262
查看次数

C#WPF BitmapSource内存泄漏?

我正在开发一个BlackJack程序,它显示了BlackJack表,卡片等.计划是它将通过自动化策略一个接一个地玩数千手牌.

我有一个PlayerSeat UserControl,它包含一个绑定到ObservableCollection的ItemsControl.此CardInHand类包含名为CardImage的BitmapSource.当实例被装箱时,它使用以下代码从资源加载卡片图像:

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

private BitmapSource GenerateCardImage() {
        Stream TempStream = this.GetType().Assembly.GetManifestResourceStream("BlackJack.Resources.CardImages.Card_" + m_Card.ShortTitle + ".gif");
        System.Drawing.Bitmap sourceBMP = new System.Drawing.Bitmap(TempStream);
        BitmapSource tempBitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
            sourceBMP.GetHbitmap(),
            IntPtr.Zero,
            System.Windows.Int32Rect.Empty,
            BitmapSizeOptions.FromWidthAndHeight(sourceBMP.Width, sourceBMP.Height)
        );
        TempStream.Dispose();
        DeleteObject(sourceBMP.GetHbitmap());
        return tempBitmapSource;
}
Run Code Online (Sandbox Code Playgroud)

问题是,在我运行~500轮(~4000手或~10000卡)后,我最终得到了GDI +错误,应用程序占用了大约400MB的RAM.这种增长很快,并且与已经玩过的手的数量有关.

DeleteObject()是我在另一个站点上发现的,它说这是从Bitmap释放资源的最佳方法.这可能会产生一些影响,但不是我正在寻找的东西.我也尝试过Dispose().

另一个网站表示它与ItemsSource绑定有关.我删除了绑定,内存仍然增长.反过来,我离开了绑定并删除了生成位图的代码.它打了4万发子弹并且没有大幅度增长(在运行的40分钟内可能+ 20MB).

每一轮后,ObservableCollection都是Clear().我已经尝试将集合,CardInHand和BitmapSource属性归零,但无济于事.

如何让这些图像显示在屏幕上,同时确保它们的对象在不再需要后会被破坏?

感谢您的时间.

c# wpf memory-leaks bitmapsource

5
推荐指数
1
解决办法
7058
查看次数

来自嵌入式图像的BitmapSource

我的目标是在WPF窗口上绘制图像"someImage.png",它是嵌入式资源,在重写的OnRender方法中:

protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
{
    base.OnRender(drawingContext);            
    drawingContext.DrawImage(ImageSource, Rect);            
}
Run Code Online (Sandbox Code Playgroud)

我找到了将我的图像从资源转换为Stream的代码:

public BitmapSource GetSourceForOnRender()
{
    System.Reflection.Assembly myAssembly = System.Reflection.Assembly.GetExecutingAssembly();
    Stream myStream = myAssembly.GetManifestResourceStream("KisserConsole.someImage.png");

    // What to do now?

    return //BitmapSource    
Run Code Online (Sandbox Code Playgroud)

}

但是我现在如何获得或创建BitmapSource?

c# wpf bitmapsource embedded-resource .net-assembly

5
推荐指数
1
解决办法
3451
查看次数

如何读取BitmapSource四个角的像素?

我有一个.NET BitmapSource对象.我想读取位图角落的四个像素,并测试它们是否都比白色更暗.我怎样才能做到这一点?

编辑:我不介意将此对象转换为具有更好API的其他类型.

.net c# wpf bitmapsource

4
推荐指数
1
解决办法
3547
查看次数

为什么这个位图图像在我加载后会改变它的大小?

快速提问:

我有这个1000 x 1000位图图像:

在此处输入图片说明

我使用这个例程来加载它:

private BitmapSource initialBitmap = new BitmapImage(new Uri("C:\\Users\\...\\Desktop\\Original.bmp"));
Run Code Online (Sandbox Code Playgroud)

为什么在我加载它之后,并在我跨过上面的行之后,我看到它是800 x 800

在此处输入图片说明

PS 我希望它是 1000 x 1000 并且不使用任何调整大小功能。它正在工作,突然变成了 800*800 !

c# bitmap bitmapsource

4
推荐指数
2
解决办法
2349
查看次数