繁体   English   中英

WPF'地图'控件; 使用画布显示大量位图图像

[英]WPF 'Map' control; using canvas to display lots of bitmap images

我正在使用Substrate解析minecraft文件数据。 Minecraft由“块”组成,块由块组成。 所以我有一个spritesheet与不同的16x16瓷砖。 我在WPF中使用croppedbitmap来查找合适的图形切片以构成地图的一部分。 然后我在WPF中指定一个Image()控件'source',这是我的croppedbitmap。 最后,我做了myCanvas.Children.Add(myImage)...问题是在我的画布中大约30个左右的图像后,应用程序变慢了爬行速度。 这是一个问题,因为典型的我的地图将有数百或数千个图像。 有没有更好的方法来绘制大量的位图数据? 我喜欢使用Image控件,因为我可以将工具提示放在地图上并使其具有交互性。 但我接受一个I​​mage控件可能更昂贵,并且有数千个可能无法工作。 这是我的代码。 (这只解析某个值的tile,因此如果id == 9)

     var mapTiles = (BitmapImage)FindResource("mapTiles");
         CroppedBitmap waterImage = new CroppedBitmap(mapTiles, new Int32Rect(352, 48, 16, 16));
         CroppedBitmap grassImage = new CroppedBitmap(mapTiles, new Int32Rect(0, 0, 16, 16));
         foreach (ChunkRef chunk in chunkManager)
         {
             countOfTiles++;

             for (int x = 0; x <= 15; x++)
             {
                 for (int z = 0; z <= 15; z++)
                 {
                     int height = chunk.Blocks.GetHeight(x, z);
                     //TODO: Normalize Chunk X, Z so 0,0 is the smallest chunk so everything is visible on the canvas.
                     if (height > 0 && chunk.X > 0 && chunk.Z > 0)
                     {
                         var block = chunk.Blocks.GetBlock(x, height - 1, z);

                         if (block.ID == 9)
                         {
                             //352, 48
                             Image image = new Image();
                             image.Source = waterImage;
                             worldMap.Children.Add(image);
                             Canvas.SetTop(image, (chunk.X + x) * 16);
                             Canvas.SetLeft(image, (chunk.Z + z) * 16);
                             image.ToolTip = countOfTiles.ToString();
                         }

您可以使用ImageBrush而不是使用较重的Image:

// use ImageBrush's instead
var waterImage = new ImageBrush(new CroppedBitmap(...));
var grassImage = new ImageBrush(new CroppedBitmap(...));

waterImage.Freeze();
grassImage.Freeze();

后来:

if (block.ID == 9)
{
    var water = new Rectangle
    {
        Width = 16,
        Height = 16,
        Fill = waterImage
    };
    worldMap.Children.Add(water);
    Canvas.SetTop(water, (chunk.X + x) * 16);
    Canvas.SetLeft(water, (chunk.Z + z) * 16);
    water.ToolTip = countOfTiles.ToString();
}

如果我遗漏了Freeze,我无法获得具有100x100平铺世界的测试应用程序以正确显示。 当我冻结每个画笔时,我可以让地图无缝显示到大约300x300。 在1000x1000它几乎不加载,但此时你需要考虑虚拟化视图,因为UI不会优雅地处理那么多UIElement。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM