windows 在 C# 中访问单个像素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/476255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Access to a single pixel in C#
提问by
I'm working on a school project right now. It's meant to be a 3D editing software, (like a very minimized version of Maya). I have to write it in C#, using the 'Windows Application Project'. I intend to implement all the 3D stuff myself, from projections to shading. My question is, how can I get direct access to a single pixel in the C# windows application? I know I'm going to have a main view port in the window. But I haven't decided yet how it will be made. Is there a built in object that I can use, that will let me define the boundaries of the view port, and then paint each pixel individually? (I'm just shooting in the dark here, I don't know much about C#. I mostly program in C)
我现在正在做一个学校项目。它是一个 3D 编辑软件,(就像一个非常小的 Maya 版本)。我必须使用“Windows 应用程序项目”用 C# 编写它。我打算自己实现所有 3D 内容,从投影到着色。我的问题是,如何直接访问 C# windows 应用程序中的单个像素?我知道我将在窗口中有一个主视口。但我还没有决定它将如何制作。是否有我可以使用的内置对象,它可以让我定义视口的边界,然后单独绘制每个像素?(我只是在这里暗中拍摄,我对 C# 不太了解。我主要用 C 编程)
Thanks, Malki.
谢谢,马尔基。
回答by Lucas Jones
Using the CreateGraphics() method, this should work:
使用 CreateGraphics() 方法,这应该可以工作:
Bitmap b = new Bitmap(Width, Height, this.CreateGraphics());
//pixel is:
Color c = b.GetPixel(x, y);
To set a pixel to a specific colour, use this instead of Color c = b.GetPixel(x,y)
:
要将像素设置为特定颜色,请使用它而不是Color c = b.GetPixel(x,y)
:
b.SetPixel(x, y, c); // where c is a Color
If you want a viewport, place a panel or a PictureBox (maybe with Dock: Fill), then use:
如果您想要一个视口,请放置一个面板或一个图片框(可能带有 Dock:Fill),然后使用:
Bitmap b = new Bitmap(viewport.Width, viewport.Height, viewport.CreateGraphics());
instead of the first line used previously.
而不是之前使用的第一行。
But from what you want to do, I think it would be better to use the OnPaint event:
但是从你想做的事情来看,我认为使用 OnPaint 事件会更好:
void pnlViewport_Paint(object sender, PaintEventArgs e) {
if ( e.ClipRectange.Width < 1 || e.ClipRectangle.Height < 1 ) return;
Bitmap b = new Bitmap(e.ClipRectangle.Width, e.ClipRectangle.Height, e.Graphics);
// ...
}
This event fires every time the control needs painted. The first line checks whether the area being drawn is empty - this will not just save CPU time, but your application may crash - you are getting it to make a 0x0 bitmap.
每次控件需要绘制时都会触发此事件。第一行检查正在绘制的区域是否为空——这不仅会节省 CPU 时间,而且你的应用程序可能会崩溃——你正在让它制作一个 0x0 位图。
EDIT: Yes, this is resizable, if Dock = DockStyle.Fill; As your window resizes, the control expands to fill the space. It is then repainted - firing the event.
编辑:是的,这是可调整大小的,如果 Dock = DockStyle.Fill; 当您的窗口调整大小时,控件会扩展以填充空间。然后重新绘制 - 触发事件。
EDIT 2: As pointed out by others, this is still slow. It does sound like it is a requirement to do the 3D drawing yourself, so maybe SDL.NET(which I think can use hardware acceleration) is the way to go. It even has a (slow) SurfaceControl to use.
编辑 2:正如其他人所指出的,这仍然很慢。听起来确实需要自己进行 3D 绘图,所以也许SDL.NET(我认为可以使用硬件加速)是可行的方法。它甚至有一个(缓慢的)SurfaceControl 可供使用。
回答by John Fisher
Christian Graus has several good graphic-manipulation articles on www.CodeProject.com. They should answer your questions.
Christian Graus 在 www.CodeProject.com 上有几篇很好的图形处理文章。他们应该回答你的问题。
回答by Vilx-
A 3D editor application needs not only to draw on the screen - it needs to do it damn fast. The standard approach in .NET would be using Bitmap and Graphics classes, like described by person-b. But this will be slow. You can improve speed by using Bitmap.LockBits()and clever optimizations, but all in all I doubt you will still get the performance you need. You'll eat away all the CPU and will still be stuck with less than some 10-20 FPS (number is a wild guess). Hardware acceleration is the real way to go. shuggycoukhas links in the right direction.
一个 3D 编辑器应用程序不仅需要在屏幕上绘图 - 它需要快速完成。.NET 中的标准方法是使用 Bitmap 和 Graphics 类,如person-b 所述。但这会很慢。您可以通过使用Bitmap.LockBits()和巧妙的优化来提高速度,但总而言之,我怀疑您仍然会获得所需的性能。你会吃掉所有的 CPU,并且仍然会被卡在不到 10-20 FPS 的情况下(数字是一个疯狂的猜测)。硬件加速是真正的方法。shuggycouk有正确方向的链接。
Unfortunately the hardware approach will also take away the projections and shading, because that's what the hardware is there for. So I don't know if you can use that... Perhaps seek information on "overlays" in .NET. That's the way all the media player software display movies. It's definately way faster than standard GDI/GDI+ and is still 2D. Or perhaps you could do a tricky workaround with DirectX - use it for drawing 2D shapes you define yourself. ;)
不幸的是,硬件方法也会消除投影和阴影,因为这就是硬件的用途。所以我不知道你是否可以使用它......也许在 .NET 中寻找有关“覆盖”的信息。这就是所有媒体播放器软件显示电影的方式。它绝对比标准 GDI/GDI+ 快得多,并且仍然是 2D。或者,也许您可以使用 DirectX 做一个棘手的解决方法 - 使用它来绘制您自己定义的 2D 形状。;)
回答by gimel
If you have a need for pixel speed, high-speed-graphing-control-for-net-or-mfc, may provide some tips.
如果您对像素速度有需求,high-speed-graphing-control-for-net-or-mfc可能会提供一些提示。
回答by ShuggyCoUk
If you are doing 3d it would make sense to make use of the hardware acceleration provided by almost every GPU under the sun these days. IF you are happy to stay with windows specific apis then DirectX's 3D API's are exposed via managed wrappersnow. Also there is the XNAtoolset designed primarily with games in mind but it provides a wealth of examples of how to do Direct-X 3D accelerated drawing from c#.
如果你正在做 3d,那么利用现在几乎每个 GPU 提供的硬件加速是有意义的。如果您乐于使用特定于 Windows 的 API,那么 DirectX 的 3D API 现在将通过托管包装器公开。还有XNA工具集主要是为游戏设计的,但它提供了大量示例,说明如何从 c# 进行 Direct-X 3D 加速绘图。