加快图像处理速度
这是我的问题的后续内容 如何将图像处理为背景到 CAD 应用程序
我应用了调整大小/重新采样代码,但它没有任何区别。我确信我对 GDI+ 等了解不够,所以如果我看起来很困惑,请原谅。
我正在使用第三方图形库(Piccolo)。除了它最终封装了 GDI+ 之外,我不太了解它在幕后做了什么。
我的测试是以不同的缩放级别旋转显示 - 这是导致性能最差的过程。我知道我正在旋转相机视图。在缩放级别高达 1.0 时,性能不会下降,并且使用鼠标滚轮旋转也很顺畅。图像必须在缩放级别 1.0 下缩放至每像素 1m 的 CAD 单位。我已经调整了图像的大小/重新采样以匹配该图像。我根据上一个问题中给出的代码尝试了不同的方法来加快速度:
public static Bitmap ResampleImage(Image img, Size size) {
using (logger.VerboseCall()) {
var bmp = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppPArgb);
using (var gr = Graphics.FromImage(bmp)) {
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;
gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
gr.DrawImage(img, new Rectangle(Point.Empty, size));
}
return bmp;
}
}
我猜这会加快重新采样的速度,但据我所知,当尝试以高缩放级别旋转显示时,这对性能没有影响。使用性能分析器(ANTS)我能够找到导致性能下降的代码:
protected override void Paint(PPaintContext paintContext) {
using (PUtil.logger.DebugCall()) {
try {
if (Image != null) {
RectangleF b = Bounds;
Graphics g = paintContext.Graphics;
g.DrawImage(image, b);
}
}
catch (Exception ex) {
PUtil.logger.Error(string.Format("{0}\r\n{1}", ex.Message, ex.StackTrace));
//----catch GDI OOM exceptions
}
}
}
性能下降完全在 g.DrawImage(image, b); 中
Bounds 当然是图像的边界。 catch 块用于捕获 GDI+ OOM 异常,这些异常在高缩放级别下看起来也更糟。
调用此函数的次数似乎随着缩放级别的增加而增加......
在绘制相机视图的代码中还有另一个命中,但我还没有足够的信息来解释这一点,除了这似乎绘制了所有附加的图层到相机 - 以及我假设的所有对象 - 当相机视图矩阵和剪辑应用于paintContext时(无论这意味着什么)。
那么是否还有其他调用 g.DrawImage(image, b);我可以用吗?还是我受到图形引擎的摆布?不幸的是,它是如此嵌入,对我来说很难改变,
再次感谢
This is a follow on to my question How To Handle Image as Background to CAD Application
I applied the resizing/resampling code but it is not making any difference. I am sure I do not know enough about GDI+ etc so please excuse me if I seem muddled.
I am using a third party graphics library (Piccolo). I do not know enough to be sure what it is doing under the hood other than it evenually wraps GDI+.
My test is to rotate the display at different zoom levels - this is the process that causes the worst performance hit. I know I am rotating the camera view. At zoom levels up to 1.0 there is no performance degradation and rotation is smooth using the mouse wheel. The image has to be scaled to the CAD units of 1m per pixel at a zoom level of 1.0. I have resized/ resampled the image to match that. I have tried different ways to speed this up based on the code given me in the last question:
public static Bitmap ResampleImage(Image img, Size size) {
using (logger.VerboseCall()) {
var bmp = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppPArgb);
using (var gr = Graphics.FromImage(bmp)) {
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;
gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
gr.DrawImage(img, new Rectangle(Point.Empty, size));
}
return bmp;
}
}
I guess this speeds up the resample but as far as I can tell has no effect on the performance when trying to rotate the display at high zoom levels. User a performance profiler (ANTS) I am able to find the code that is causing the performance hit:
protected override void Paint(PPaintContext paintContext) {
using (PUtil.logger.DebugCall()) {
try {
if (Image != null) {
RectangleF b = Bounds;
Graphics g = paintContext.Graphics;
g.DrawImage(image, b);
}
}
catch (Exception ex) {
PUtil.logger.Error(string.Format("{0}\r\n{1}", ex.Message, ex.StackTrace));
//----catch GDI OOM exceptions
}
}
}
The performance hit is entirely in g.DrawImage(image, b);
Bounds is the bounds of the image of course. The catch block is there to catch GDI+ OOM exceptions which seem worse at high zoom levels also.
The number of times this is called seems to increase as the zoom level increases....
There is another hit in the code painting the camera view but I have not enough information to explain that yet except that this seems to paint all the layers attached to the camera - and all the objects on them I assume - when when the cameras view matrix and clip are applied to the paintContext (whatever that means).
So is there some other call to g.DrawImage(image, b); that I could use? Or am I at the mercy of the graphics engine? Unfortunately it is so embedded that it would be very hard to change for me
Thanks again
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果我没记错的话,我认为您使用的是 Piccolo 形式的 PImageNode 对象。对该方法的调用数量可能会增加,因为 Piccolo 引擎根据缩放级别(某种剔除)跟踪用户屏幕上的“真实”绘图区域,并仅绘制可见节点。如果场景中有很多 PImageNode 对象并进行 ZoomOut ,则会增加需要绘制的 PImageNode 对象的数量,因此调用该方法。
性能怎么样:
1)尝试使用 SetStyle(ControlStyles.DoubleBuffer,true); PCanvas 的(如果尚未设置)
2)请查看此处 CodeProject
问候。
I think you you use,if I'm not mistake, PImageNode object form Piccolo. The quantity of calls to that method could increase because Piccolo engine traces "real" drawing area on the user screen, based on zoom level (kind of Culling) and draws only the nodes which are Visible ones. If you have a lot of PImageNode objects on your scene and make ZoomOut it will increase the quantity of PImageNode objects need to be drawn, so the calls to that method.
What about the performance:
1) Try to use SetStyle(ControlStyles.DoubleBuffer,true); of the PCanvas (if it's not yet setted up)
2) look here CodeProject
Regards.