为何Gdiplus::Region::IsEmpty()方法需要传入Graphics对象?
为什么Gdiplus::Region::IsEmpty需要传入Graphics对象?
你编写的判断Gdiplus路径与矩形相交的函数运行正常,但疑惑为什么IsEmpty()必须传入一个Graphics对象,先看你的代码:
bool objects_intersect(Gdiplus::GraphicsPath* path, Gdiplus::Pen* path_pen, Gdiplus::RectF& rectangle) { // 获取路径覆盖的区域,包括其轮廓。 Gdiplus::GraphicsPath* footprint = path->Clone(); footprint->Widen(path_pen); Gdiplus::Region footprint_region(footprint); delete footprint; // 获取路径与矩形的重叠区域 footprint_region.Intersect(rectangle); // 测试重叠区域是否非空 Gdiplus::Bitmap blank_image(10, 10); Gdiplus::Graphics throwaway_graphics(&blank_image); // 这有必要吗? return !footprint_region.IsEmpty(&throwaway_graphics); }
核心原因:Region是设备无关的,但判断空区域需要设备上下文信息
GDI+里的Region对象本身是设备无关的——它存储的是抽象的区域形状定义,不绑定具体的显示设备或绘图环境。但IsEmpty()方法要判断的是:这个区域在当前绘图环境下是否实际占据了任何像素空间,这就需要依赖Graphics对象提供的以下关键信息:
- 当前的坐标系变换(比如缩放、平移、旋转)
- 设备的分辨率(DPI)
- 裁剪区域限制
举个例子:如果你的Graphics设置了2倍缩放,原本一个1x1的小Region,在这个环境下会被放大成2x2的像素区域,IsEmpty需要结合这个缩放比例才能准确判断它是否为空。如果没有Graphics提供的上下文,方法无法确定该用什么规则来计算区域的实际覆盖范围,直接调用会导致行为不确定甚至报错。
你代码里的"临时Graphics"为什么可行?
你创建的throwaway_graphics绑定了一个空白Bitmap,这个Graphics提供了默认的无变换绘图上下文(没有缩放、平移,DPI为系统默认),刚好满足IsEmpty方法对合法上下文的需求,能让它基于标准规则判断区域是否为空。这种写法是合理的,因为你只需要一个合法的、无特殊变换的上下文来完成判断,不需要实际绘制任何内容。
补充:有没有更高效的写法?
其实可以不用创建Bitmap,直接通过屏幕DC创建临时Graphics(不过需要注意释放DC),但你的写法已经足够简洁且安全,没必要特意修改。
内容的提问来源于stack exchange,提问作者Liam Bohl
相关产品推荐
相关产品推荐

