小编Aro*_*okh的帖子

C#从System.Drawing.Bitmap有效获取像素数据

我在HDD上有几个(~2GB)原始24bpp RGB文件.现在我想要检索它的一部分并将其缩放到所需的大小.
(唯一允许的比例是1,1/2,1/4,1/8,......,1/256)

所以我现在正在从感兴趣的矩形中读取每一行到一个数组,这给我留下了一个高度正确但宽度错误的位图.

下一步我是从新创建的数组创建一个Bitmap.
这是通过使用指针完成的,因此不会复制涉及的数据.
接下来,我在Bitmap上调用GetThumbnailImage,它创建一个具有正确尺寸的新位图.

现在我想返回新创建的位图的原始像素数据(作为字节数组).但要实现这一点,我目前正在使用LockBits将数据复制到一个新数组中.

所以我的问题是:有没有办法将像素数据从Bitmap转换为字节数组而不复制它?

就像是:

var bitmapData = scaledBitmap.LockBits(...)
byte[] rawBitmapData = (byte[])bitmapData.Scan0.ToPointer()
scaledBitmap.UnlockBits(bitmapData)
return rawBitmapData 
Run Code Online (Sandbox Code Playgroud)

我很清楚这不起作用,它只是我基本上想要实现的一个例子.

c# resize pixel bitmap

12
推荐指数
1
解决办法
2万
查看次数

无法捕获由PInvoke调用的C dll引起的异常

我正在编写一个使用最新MediaInfoLib Dll的C#.NET 3.5程序.
它似乎导致某些文件的异常.

我想捕获这些异常并确保我的程序继续运行,
但由于某种原因我无法通过简单的try/catch语句捕获它.

PInvoke方法:

    [DllImport("MediaInfo.dll")]
    private static extern IntPtr MediaInfo_New();
    [DllImport("MediaInfo.dll")]
    private static extern IntPtr MediaInfo_Open(IntPtr Handle,MarshalAs(UnmanagedType.LPWStr)] string FileName);
Run Code Online (Sandbox Code Playgroud)

用法:

    Handle = MediaInfo_New();
    try{
        MediaInfo_Open(Handle, FileName)
    } catch { } 
Run Code Online (Sandbox Code Playgroud)

调用MediaInfo_Open(Handle,FileName)可能会导致异常.
我的程序退出并且"vshost32-clr2.exe"崩溃,而不是使用try/catch语句捕获错误.(它也作为发布版本崩溃并且没有附带调试器)
在搜索网络后,我发现有人建议检查"启用非托管代码调试",这只导致我的程序退出而没有vshost32-clr2.exe崩溃.

知道如何捕捉异常吗?

c# pinvoke exception try-catch .net-3.5

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

C#快速/高效地压缩大量数据块

我有大约270k个数据块对,每对包含一个32KiB和一个16KiB块.

当我将它们保存到一个文件时,我当然得到一个非常大的文件.但数据很容易压缩.
使用WinRAR压缩5.48GiB文件后,压缩率很高,生成的文件大小为37.4MiB.

但我需要随机访问每个单独的块,所以我只能单独压缩块.
为此我使用了.NET提供的Deflate类,它将文件大小减小到382MiB(我可以使用).
但速度不够好.

很多速度损失可能是因为总是为每个块创建一个新的MemoryStream和Deflate实例.但似乎它们不是为了重复使用而设计的.

我猜(很多?)当使用"全局"字典而不是每个块有一个时,可以实现更好的压缩.

是否有适合该任务的压缩算法(最好是在C#中)的实现?

以下链接包含每个字节数出现的百分比,分为三种块类型(仅限32KiB块).第一种和第三种类型的出现率为37.5%,第二种类型为25%. 块类型百分比

长文件短篇小说:Type1主要包含一个.Type2主要由零组成,Type3主要由零组成.大于128的值不会出现(尚未).

16KiB块几乎总是由零组成

c# compression block

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

根据 Avalonia 中的 DataContext 属性选择 DataTemplate

我正在实现一个 UserControl ,它应该显示设置列表:

public class SettingPropertyItem {
    string Name { get; }
    Type ValueType { get; }
    object Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

基于每种类型,ValueType应使用不同的 DataTemplate。
为了促进这一点,UserControl 有以下 Control,并以 aSettingPropertyItem作为其 DataContext:

<UserControl x:Class="AVDump3Gui.Controls.Settings.SettingsView">
    ...
    <ItemsControl Items="{Binding Properties}" Margin="16,0,0,0">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
            ...
                <ContentControl Content="{Binding}"/>
            ...
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    ...
</UserControl>
Run Code Online (Sandbox Code Playgroud)

然后在使用 Usercontrol 的视图中,我在其 DataTemplates 中添加了一个 DataTemplate:

<sv:SettingsView.DataTemplates>
  <DataTemplate DataType="{x:Type vm:SettingPropertyItem}">
    ...
  </DataTemplate>
</sv:SettingsView.DataTemplates>
Run Code Online (Sandbox Code Playgroud)

到目前为止一切顺利,一切都按预期进行。但现在我有点困惑,因为我不知道如何基于 DataContext 中的属性应用不同的 DataTemplate。
对于 WPF,DataTemplateSelector 或触发器似乎是可行的方法(忽略其他框架),但它们在 Avalonia 中似乎不存在。我也尝试过样式,但选择器似乎无法访问 DataContext 属性。

如何才能做到这一点?

c# datatemplate datatemplateselector avaloniaui

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

C#NET4.0任务保持参考

我一直在调试我的程序,因为它抛出Out Of Memory异常.
剥离后,看起来任务正在保持参考,尽管它已经完成.
这是我的精简代码:

public class Program {
    static void Main(string[] args) {
        var cts = new CancellationTokenSource();
        ConsumeFiles(cts.Token);
    }

    public static void ConsumeFiles(CancellationToken ct) {
        while(true) {
            var dataSource = new Queue<byte[]>();
            for(int i = 0;i < 16;i++) {
                var block = new byte[4 * 1024 * 1024];
                for(int j = 0;j < block.Length;j++) block[j] = (byte)j;
                dataSource.Enqueue(block);
            }

            var cts = new CancellationTokenSource();
            ct.Register(() => cts.Cancel()); //Remove this line => No OOM

            Task.Factory.StartNew(() => { //Remove Task …
Run Code Online (Sandbox Code Playgroud)

c# reference task

3
推荐指数
1
解决办法
532
查看次数