gpt4 book ai didi

c# - 我什么时候应该在 WPF 应用程序中使用 PixelFormats.Pbgra32?

转载 作者:太空宇宙 更新时间:2023-11-03 12:36:24 27 4
gpt4 key购买 nike

考虑以下设置:我在磁盘上有一些图像。我无法修改这些图像,因为它们属于另一个项目。我刚读完。

我需要对它们进行处理以使其在我的应用中看起来最佳。我的意思是像素着色器已处理。当我完成处理后,输出图像将用作某种 ListView 或其他控件中的缩略图。

我选择 PixelFormats.Bgra32 作为输出格式,因为为它构建像素着色器非常简单。然而,我读到 PixelFormats.Pbgra32 由 Windows native 使用,因此速度更快。

在图像上使用淡入淡出效果时,它是否仍然更快?在托管代码中预乘 channel 而不是将其留给框架是否有意义?

最佳答案

所以我测试了它(用/unsafe 编译):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

namespace BgraVsPbgra {

public partial class MainWindow : Window {

readonly WrapPanel Panel;
readonly TextBlock Output;
readonly PixelFormat FN = PixelFormats.Bgra32;
readonly PixelFormat FP = PixelFormats.Pbgra32;
readonly List<long> TN = new List<long>();
readonly List<long> TP = new List<long>();
DateTime T0;
long DT => (DateTime.Now - T0).Ticks;
DateTime Now => DateTime.Now;

public MainWindow() {
InitializeComponent();
SizeToContent = SizeToContent.WidthAndHeight;
Title = "Bgra32 vs Pbgra Benchmark";
Panel = new WrapPanel {
Width = 512,
Height = 512
};
Output = new TextBlock {
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Foreground = new SolidColorBrush(Colors.White)
};
(Content as Grid).Children.Add(Panel);
(Content as Grid).Children.Add(Output);
Dispatcher.BeginInvoke(new Action(() => Start()), DispatcherPriority.SystemIdle);
}

private async void Start() {
Output.Text += "Bgra32 vs Pbgra32 benchmark started.\r\n\r\n";
var t0 = DateTime.Now;
var n = 3;
var i = 16384;
for (var p = 1; p <= n; p++) {
Output.Text += $"\r\nPass {p}/{n}.\r\n\r\n";
await Benchmark(i / 4, 0.75, true);
await Benchmark(i / 4, 0.75, false);
await Benchmark(i / 4, 1, true);
await Benchmark(i / 4, 1, false);
}
var t = (DateTime.Now - t0).TotalSeconds;
Output.Text += $"\r\nDone in {t:0.0}s.\r\n";
}

private async Task Benchmark(int n = 256, double opacity = 1, bool cheat = false) {
Output.Text += $"Benchmarking with opacity = {opacity}... ";
if (cheat) Output.Text += "CHEATING!... ";
//Output.Text += "\r\n";
for (int i = 0; i < n; i++) await Dispatcher.BeginInvoke(new Action(async () => await DrawTestAsync(opacity, cheat)), DispatcherPriority.Send);
Output.Text += ($"Pbgra32 advantage: {(TN.Average() / TP.Average() * 100d - 100d):0.0}%\r\n");
}

async Task DrawTestAsync(double opacity = 1, bool cheat = false) {
await Dispatcher.BeginInvoke(new Action(() => {
Panel.Children.Clear();
for (int i = 0; i < 8; i++) {
T0 = Now; Panel.Children.Add(new Image { Source = CreateBitmap(FP, cheat), Width = 128, Height = 128, Opacity = opacity }); TP.Add(DT);
T0 = Now; Panel.Children.Add(new Image { Source = CreateBitmap(FN, cheat), Width = 128, Height = 128, Opacity = opacity }); TN.Add(DT);
}
}), DispatcherPriority.Send);

}



BitmapSource CreateBitmap(PixelFormat pixelFormat, bool cheat = false) {
var bitmap = new WriteableBitmap(256, 256, 96, 96, pixelFormat, null);
bitmap.Lock();
unsafe
{
var pixels = (uint*)bitmap.BackBuffer;
if (pixelFormat == FN || cheat)
for (uint y = 0; y < 256; y++) for (uint x = 0; x < 256; x++) pixels[x + y * 256] = 0x80000000u | (x << 16) | y;
else
for (uint y = 0; y < 256; y++) for (uint x = 0; x < 256; x++) pixels[x + y * 256] = 0x80000000u | (x / 2 << 16) | y / 2;
}
bitmap.Unlock();
bitmap.Freeze();
return bitmap;
}

}

}

我得到的结果相当随机,但大多数时候使用 Pbgra32 像素格式似乎比使用 Bgra32 像素格式快一点(大约 3%)。

当使用 Pbgra32 格式时,必须为每个 channel 进行一些额外的操作,但是 2 个额外的划分似乎没有产生任何可测量的差异。

因此,如果你想让你的位图快大约 3%,请使用 Pbgra32 格式和预乘 channel ,如 pr = r * a/255,这可能看起来像:

uint pixel = a << 24 | r * a / 255 << 16 | g * a / 255 << 8 | b * a / 255;

并且不要创建 pixel 函数,否则会影响性能。说到性能,不安全的像素操作似乎比使用安全的 CopyPixels()/WritePixels() 方法快 2 到 3 倍。

不,我不会使用 Pbgra32 创建位图或位图的像素着色器。我的意见是:不值得。如果我错了,请纠正我。

关于c# - 我什么时候应该在 WPF 应用程序中使用 PixelFormats.Pbgra32?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40826742/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com