wpf - 应用 <Image.Effect> 后如何获取 BitmapImage 字节

标签 wpf image shader

这个:

BitmapSource originalImage;
byte[] _originalPixels;
_originalPixels = new byte[(int) originalImage.Width*(int) originalImage.Height*4];
originalImage.CopyPixels(_originalPixels, 4*(int) originalImage.Width, 0);

在应用过滤器之前复制图像字节,这并不奇怪。

如何获取已应用效果的字节?

如何以编程方式将着色器效果应用于 byte[] 或某种低级像素结构数组?

最佳答案

助手:

public static class ImageRenderingHelper
    {
        public static BitmapSource RenderToBitmap(FrameworkElement target)
        {
            int actualWidth = (int)target.ActualWidth;
            int actualHeight = (int)target.ActualHeight;

        Rect boundary = VisualTreeHelper.GetDescendantBounds(target);
        RenderTargetBitmap renderBitmap = new RenderTargetBitmap(actualWidth, actualHeight, 96, 96, PixelFormats.Pbgra32);

        DrawingVisual drawingVisual = new DrawingVisual();
        using (DrawingContext context = drawingVisual.RenderOpen())
        {
            VisualBrush visualBrush = new VisualBrush(target);
            context.DrawRectangle(visualBrush, null, new Rect(new Point(), boundary.Size));
        }

        renderBitmap.Render(drawingVisual);
        return renderBitmap;
    }

    private static void Arrange(UIElement element, int width, int height)
    {
        element.Measure(new Size(width, height));
        element.Arrange(new Rect(0, 0, width, height));
        element.UpdateLayout();
    }

    public static byte[] RenderImageWithEffects(ImageSource image, IEnumerable<ShaderEffect> effects)
    {
        effects = effects.Reverse();
        Grid root = new Grid();
        Arrange(root, (int)image.Width, (int)image.Height);
        Grid current = root;
        foreach (var shaderEffect in effects)
        {
            var effect = new Grid();
            Arrange(effect, (int)image.Width, (int)image.Height);
            effect.Effect = shaderEffect;
            current.Children.Add(effect);
            current = effect;
        }

        Image img = new Image();
        img.Source = image;
        Arrange(img, (int)image.Width, (int)image.Height);
        current.Children.Add(img);
        BitmapSource bs = RenderToBitmap(root);
        byte[] buffer = new byte[(int)bs.Width * (int)bs.Height * 4];
        bs.CopyPixels(buffer, 4 * (int)bs.Width, 0);
        return buffer;
    }

    public static byte[] RenderImageWithEffects(string imagePath, IEnumerable<ShaderEffect> effects)
    {
        BitmapImage bmp = new BitmapImage(new Uri(imagePath, UriKind.Absolute));
        return RenderImageWithEffects(bmp, effects);
    }
}

关于wpf - 应用 <Image.Effect> 后如何获取 BitmapImage 字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5769863/

相关文章:

c# - 如何为 PathGeometry 设置动画以使其缓慢显示?

wpf - PostSharp NotifyPropertyChanged 模型 - PropertyChangedEventHandler

ios - 按下 iOS swift 后更改 UIBarButtonItem 图标

html - 如何使用 Pandoc 将带有数字的 DOCX 文件转换为使用 base64 的独立 HTML 文件?

c# - 我的着色器在桌面上工作,但屏幕在 Android 上变黑

opengl - 为什么这个 OpenGL 程序不绘制三角形?

c# - 使用匿名类型过滤 ICollectionView 但需要 Predicate<object>?

c# - 数据绑定(bind) ComboBox 中的本地化无法正常工作

javascript - HTML/javascript 客户端图像压缩看起来是一个合理且万无一失的计划吗?

c++ - 着色玩具到 SFML