【发布时间】:2012-08-29 04:29:30
【问题描述】:
问题已回答。有关更多信息,请查看本文末尾的 EDIT #4。
我们目前正在开发一个运行良好的游戏引擎。我正在开发动画创建器,想知道是否可以使用加法混合绘制图像。
让我解释一下。
我们使用 C# 的 System.Drawing 库并使用 Windows 窗体。目前,用户可以通过导入带框动画图像(包含动画每一帧的图像)来创建动画,并且用户可以将这些帧拖放到任何他想要的地方。
实际的问题是我们无法弄清楚如何使用加法混合绘制框架。
如果您不太了解,这里有一个添加剂混合的示例。我不会怪你,我很难用英语写作。
我们使用下面的方法在 Panel 上或直接在窗体上绘制。例如,这里是为地图编辑器绘制平铺地图的代码。由于 AnimationManager 代码很乱,用这个例子会更清楚。
using (Graphics g = Graphics.FromImage(MapBuffer as Image))
using (Brush brush = new SolidBrush(Color.White))
using (Pen pen = new Pen(Color.FromArgb(255, 0, 0, 0), 1))
{
g.FillRectangle(brush, new Rectangle(new Point(0, 0), new Size(CurrentMap.MapSize.Width * TileSize, CurrentMap.MapSize.Height * TileSize)));
Tile tile = CurrentMap.Tiles[l, x, y];
if (tile.Background != null) g.DrawImage(tile.Background, new Point(tile.X * TileSize, tile.Y * TileSize));
g.DrawRectangle(pen, x * TileSize, y * TileSize, TileSize, TileSize);
}
有没有一种可能的方法来绘制一个附加绘图的图像,如果是这样,如果有人能指出我的方法,我将永远感激不尽。谢谢。
编辑#1:
为了绘制图像,我们使用颜色矩阵来设置色调和 alph(不透明度),如下所示:
ColorMatrix matrix = new ColorMatrix
(
new Single[][]
{
new Single[] {r, 0, 0, 0, 0},
new Single[] {0, g, 0, 0, 0},
new Single[] {0, 0, b, 0, 0},
new Single[] {0, 0, 0, a, 0},
new Single[] {0, 0, 0, 0, 1}
}
);
也许颜色矩阵可以用于加法混合?
编辑#2:
刚刚发现 this Mahesh Chand 的文章。
进一步浏览后,可能无法使用颜色矩阵,即使它可以完成很多关于颜色转换的工作。 如果找到解决方案,我将回答我自己的问题。
感谢您的帮助。
编辑#3:
XNA 有很多关于混合的文档here。我找到了用于在图像的每个像素上完成加法混合的公式。
PixelColor = (source * [1, 1, 1, 1]) + (destination * [1, 1, 1, 1])
也许有一种方法可以在当前上下文中使用这个公式? 我将在下一次编辑时开始 50 赏金,我们真的需要这个来工作。
再次感谢您的宝贵时间。
编辑#4
感谢 axon,现在问题解决了。使用 XNA 及其 Spritebatch,您可以完成 Additive 混合:
首先你创建一个 GraphicsDevice 和一个 SpriteBatch
// In the following example, we want to draw inside a Panel called PN_Canvas.
// If you want to draw directly on the form, simply use "this" if you
// write the following code in your form class
PresentationParameters pp = new PresentationParameters();
// Replace PN_Canvas with the control to be drawn on
pp.BackBufferHeight = PN_Canvas.Height;
pp.BackBufferWidth = PN_Canvas.Width;
pp.DeviceWindowHandle = PN_Canvas.Handle;
pp.IsFullScreen = false;
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, GraphicsProfile.Reach, pp);
batch = new SpriteBatch(device);
然后,当需要在控件或窗体上绘制时(例如使用 OnPaint 事件),您可以使用以下代码块
// You should always clear the GraphicsDevice first
device.Clear(Microsoft.Xna.Framework.Color.Black);
// Note the last parameter of Begin method
batch.Begin(SpriteSortMode.BackToFront, BlendState.Additive);
batch.draw( /* Things you want to draw, positions and other infos */ );
batch.End();
// The Present method will draw buffer onto control or form
device.Present();
【问题讨论】:
-
我不确定这是否可以在直接的 winforms 中实现,而无需自行处理像素值。是否可以选择使用 WPF 托管组件进行绘图? WPF 能够更轻松地设置混合模式。
-
@Dervall 我们搜索得越多,我们就越开始认为使用 WPF 托管组件是一个非常好的主意。如果不直接在 Winforms 中使用逐像素算法,可能就没有解决方案。或者也许有人会想出某种奇迹?
-
.DrawImage with opacity? 的可能副本
-
@HansPassant 谢谢你的信息。问题相似但不一样。您提供的链接是关于改变不透明度的,这很容易改变颜色矩阵的 [3][3] 或 [4][3] 值。我要做的是将图像与下面的图像混合,但使用加法混合,请参见图像示例。
-
这不是关于不透明度,而是关于混合。蹩脚的标题,发生了。 sn-p 中的
cm.Matrix33 = 1F - mBlend;语句是您遗漏的。
标签: c# winforms system.drawing color-blending