You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FillRectangle绘制像素化平铺纹理模糊,如何实现最近邻效果?

问题描述

我尝试通过从位图创建画笔,再使用该画笔绘制矩形来实现像素化平铺背景,代码如下:

e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.ScaleTransform(4, 4);

Bitmap tilemap = new Bitmap("tileset.png");
TextureBrush grassBrush = new TextureBrush(tilemap, WrapMode.Tile, new Rectangle(0, 0, 16, 16));

e.Graphics.FillRectangle(grassBrush, e.ClipRectangle);

但最终得到的纹理呈现模糊状态(效果截图:纹理模糊效果),请问如何让e.Graphics.FillRectangle(grassBrush, e.ClipRectangle);绘制出像素化的最近邻平铺纹理?

解决方案

问题出在TextureBrush自身的纹理采样规则未适配像素化需求,仅设置Graphics的InterpolationMode无法完全控制画笔的缩放逻辑,可通过以下方式修复:

  • 先预缩放单个Tile再创建画笔
    直接对Graphics做全局缩放会让画笔纹理被二次插值,建议先提取目标Tile并按比例缩放为清晰的像素化版本,再基于缩放后的Tile创建平铺画笔:

    // 提取16x16的目标Tile
    Bitmap tilemap = new Bitmap("tileset.png");
    Bitmap grassTile = tilemap.Clone(new Rectangle(0, 0, 16, 16), tilemap.PixelFormat);
    tilemap.Dispose();
    
    // 按4倍比例缩放Tile,确保像素化效果
    Bitmap scaledTile = new Bitmap(16 * 4, 16 * 4);
    using (Graphics g = Graphics.FromImage(scaledTile))
    {
        g.InterpolationMode = InterpolationMode.NearestNeighbor;
        g.PixelOffsetMode = PixelOffsetMode.Half; // 修正像素对齐偏差
        g.DrawImage(grassTile, 0, 0, scaledTile.Width, scaledTile.Height);
    }
    grassTile.Dispose();
    
    // 使用缩放后的Tile创建平铺画笔并绘制
    using (TextureBrush grassBrush = new TextureBrush(scaledTile, WrapMode.Tile))
    {
        e.Graphics.FillRectangle(grassBrush, e.ClipRectangle);
    }
    scaledTile.Dispose();
    
  • 配置画笔的ImageAttributes(替代方案)
    如果不想预缩放Tile,可给TextureBrush绑定ImageAttributes强制开启最近邻插值,同时调整画笔的变换匹配全局缩放:

    e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
    e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
    
    Bitmap tilemap = new Bitmap("tileset.png");
    ImageAttributes attr = new ImageAttributes();
    attr.SetInterpolationMode(InterpolationMode.NearestNeighbor);
    
    // 创建画笔时指定属性,同时设置画笔缩放抵消全局缩放的影响
    using (TextureBrush grassBrush = new TextureBrush(tilemap, WrapMode.Tile, new Rectangle(0,0,16,16)))
    {
        grassBrush.Transform = new Matrix(1/4f, 0, 0, 1/4f, 0, 0);
        e.Graphics.FillRectangle(grassBrush, e.ClipRectangle, new Rectangle(0,0,16,16), attr);
    }
    tilemap.Dispose();
    

两种方案都能确保纹理以最近邻方式采样,呈现清晰的像素化平铺效果。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 07:30:55