Подтвердить что ты не робот

Как правильно отображать большие растровые изображения в WPF?

Я не ожидал

RenderTargetBitmap.Render(visual)

чтобы иметь какие-либо побочные эффекты, вырвать изменения самих растровых данных. Похоже, это неправда. Я не могу повторить его более 60 раз, прежде чем начнутся некоторые уродливые артефакты рендеринга.

Как правильно визуализировать много спрайтов в WPF? Ниже приведен код для воспроизведения проблемы.

Я генерирую спрайты следующим образом:

    BitmapSource Sprite()
    {
        var bitmap = new RenderTargetBitmap(
            500, 500,
            96, 96,
            PixelFormats.Default);

        var visual = new DrawingVisual();
        var rect = new Rect(
                    new Size(
                        bitmap.Width,
                        bitmap.Height));

        using (DrawingContext context = visual.RenderOpen())
            context.DrawLine(
                new Pen(Brushes.Red, 100),
                rect.TopLeft,
                rect.BottomRight);

        bitmap.Render(visual);
        bitmap.Freeze();
        return bitmap;
    }

Вот, например, холст для рендеринга многих из них:

    public BitmapSource Canvas
    {
        get
        {
            var bitmap = new RenderTargetBitmap(
                1980, 1080,
                96, 96,
                PixelFormats.Default);

            var tiles = 70;
            for (int i = 0; i < tiles; i++)
            {
                var visual = new DrawingVisual();
                var rect = new Rect(
                    bitmap.Width / tiles * i,
                    0,
                    bitmap.Width / tiles,
                    bitmap.Height);

                using (DrawingContext context = visual.RenderOpen())
                    context.DrawImage(Sprite(), rect);

                bitmap.Render(visual);
            }

            bitmap.Freeze();
            return bitmap;
        }
    }

Я вижу это странное изображение, будучи привязанным к свойству Canvas...

enter image description here

4b9b3361

Ответ 1

Вот пример использования InteropBitmap:

 public InteropBitmapHelper(ColorSpace colorSpace, int bpp, int width, int height, uint byteCount)
        {
            _currentColorSpace = colorSpace;
            _pixelFormat = GetPixelFormat(colorSpace, bpp);

            if (_pixelFormat == PixelFormats.Rgb24 || _pixelFormat == PixelFormats.Rgb48 || _pixelFormat == PixelFormats.Bgr32 ||
                _pixelFormat == PixelFormats.Bgr24 || _pixelFormat == PixelFormats.Bgr565 ||
                _pixelFormat == PixelFormats.Gray16 || _pixelFormat == PixelFormats.Gray8)
            {
                int strideWidth = (width % 4 == 0) ? width : width - width % 4 + 4;
                if (byteCount != strideWidth * height * (_pixelFormat.BitsPerPixel / 8))
                {
                    strideWidth = width;
                }
                _stride = strideWidth * _pixelFormat.BitsPerPixel / 8;

                _byteCount = (uint)((_stride) * height * ((short)bpp).NumberOfBytes());

                ColorFileMapping = CreateFileMapping(new IntPtr(-1), IntPtr.Zero, 0x04, 0, _byteCount, null);

                if (ColorFileMapping == IntPtr.Zero)
                {
                    var res=GetLastError();
                    IPDevLoggerWrapper.Error("Could not generate InteropBitmap "+res);
                    return;
                }
                ViewerImageData = MapViewOfFile(ColorFileMapping, 0xF001F, 0, 0, _byteCount);
                InteropBitmap = Imaging.CreateBitmapSourceFromMemorySection(ColorFileMapping,
                                                                            width,
                                                                            height,
                                                                            _pixelFormat,
                                                                            _stride,
                                                                            0) as InteropBitmap;
            }
            else
            {
                LoggerWrapper.Error("The image format is not supported");
                return;
            }
        }

Вот как я подключаю его к xaml.

<Canvas     
    x:Name="content" 
    Width="{Binding ElementName=MainImage, Path=ActualWidth}" 
    Height="{Binding ElementName=MainImage, Path=ActualHeight}" 
    Background="Transparent"
    MouseEnter="ImageMouseEnter" 
    MouseLeave="ImageMouseLeave"
    RenderTransformOrigin ="0.5,0.5">
    <Image x:Name="MainImage"  Source="{Binding Source}" RenderOptions.BitmapScalingMode="{Binding ViewerRenderingMode }"/>

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.