我看过文章证明墨水可以与背景图像一起保存,以便墨水重叠在图像上,然后保存为单个图像文件。但是,不幸的是,我所看到的文章没有详细说明它是如何完成的。 我可以使用以下语句轻松保存背景图像:
axInkPicture1.Picture.Save(@"\path\to\file.gif");
...但背景图片上没有墨迹
我不知道有任何保存墨水的直接方法,但这就是我目前的做法:
string tempPath = Path.GetTempPath();
string tempFile = tempPath + @"\file.gif";
// save to a temp file
if (axInkPicture1.Ink.Strokes.Count > 0)
{
byte[] bytes = (byte[])axInkPicture1.Ink.Save(InkPersistenceFormat.IPF_GIF, InkPersistenceCompressionMode.IPCM_Default);
using (MemoryStream ms = new MemoryStream(bytes))
{
using (Bitmap gif = new Bitmap(ms))
{
gif.Save(tempFile);
}
}
}
这样可以保存墨水,但没有背景图像。
如何将墨迹和图像保存到单个文件中?
赞赏任何帮助或方向指示...
###编辑这是我到目前为止所尝试的其他内容
InkRectangle inkBox = axInkPicture1.Ink.GetBoundingBox();
byte[] gifbits = (byte[])axInkPicture1.Ink.Save(InkPersistenceFormat.IPF_GIF, InkPersistenceCompressionMode.IPCM_Default);
using (System.IO.MemoryStream buffer = new System.IO.MemoryStream(gifbits))
using (var inkImage = new Bitmap(buffer))
using (var picture = new Bitmap(axInkPicture1.Picture))
using (var g = Graphics.FromImage(picture))
{
g.DrawImage(inkImage, new Rectangle(inkBox.Left, inkBox.Right, axInkPicture1.Picture.Width, axInkPicture1.Height));
picture.Save(tempFile, System.Drawing.Imaging.ImageFormat.Gif);
}
...但我仍然没有运气。这样只保存背景图片而不保存墨水。我有什么想法吗?
提前致谢
答案 0 :(得分:0)
Soooo ....经过多次敲击和咬牙切齿之后,我终于找到了解决问题的方法,虽然可能不是我预期的解决方案,也许不是最好的解决方案,但它确实有效。我是c#和.net世界的新手所以如果我在这里说任何愚蠢的话,请随时纠正我。
我发现上面编辑中的代码实际上正在工作,我只是看不到墨水,因为它超出了矩形的范围。显然,使用GetBoundingBox()方法获取的矩形为您提供了与像素坐标大不相同的inkSpace坐标。
考虑到这一点,我的下一个目标是使用inkSpaceToPixels方法将inkSpace坐标转换为像素坐标。我挣扎了一段时间,并且永远无法弄清楚如何使用activePox的inkPicure或axInkPicture来做到这一点。它需要一些hdcDisplay的句柄,我无法完全理解。
最后,我使用了Microsoft.Ink.dll的.net版本(Microsoft.Ink)。我之所以使用activeX版本的唯一原因是因为出于某种原因我无法在我的开发机器上安装Windows Tablet PC SDK。它一直在抱怨我需要安装WinXP Tablet PC操作系统。我发现我可以将它安装在另一台(Win7)PC上,然后从该PC上复制.dll。
所以,这是现在正在运行的最终版本......哇!
//set the temporary file paths
string tempPath = Path.GetTempPath();
string tempFile = tempPath + @"tmpFile.png";
//get the bounding box and reference point for the ink strokes (in inkspace coordinates!)
Rectangle inkBox = inkPicture1.Ink.GetBoundingBox();
Point point = new Point(inkBox.Left, inkBox.Top);
MessageBox.Show(point.X.ToString() + ", " + point.Y.ToString());//"before" coordinates
// Convert inkspace coordinates to pixel coordinates using Renderer
Graphics tempGraphics = CreateGraphics();
Microsoft.Ink.Renderer inkRenderer = new Renderer();
inkRenderer.InkSpaceToPixel(tempGraphics, ref point);;
MessageBox.Show(point.X.ToString() + ", " + point.Y.ToString());//"after" coordinates
// Clean up
tempGraphics.Dispose();
// save the ink and background image to a temp file
if (inkPicture1.Ink.Strokes.Count > 0)
{
byte[] bytes = inkPicture1.Ink.Save(PersistenceFormat.Gif, CompressionMode.NoCompression);
using (MemoryStream ms = new MemoryStream(bytes))
{
using (Bitmap gif = new Bitmap(ms))
using (var bmp = new Bitmap(inkPicture1.BackgroundImage))
using (var g = Graphics.FromImage(bmp))
{
g.DrawImage(gif, new Rectangle(point.X, point.Y, gif.Width, gif.Height));
bmp.Save(tempFile, System.Drawing.Imaging.ImageFormat.Png);
}
}
}
对于长篇大论的解释感到抱歉,但我觉得只是在没有充分解释的情况下发布解决方案会留下太多未解决的问题......
答案 1 :(得分:0)
我想我没有足够的50个评论的声誉,所以我会回答这个评论给其他人可能会像我一样在google搜索之后落在这里:
这非常有帮助。我翻译成VB并且工作正常。
经过一些骚扰后,我发现了DLL:
C:\ Program Files(x86)\ Common Files \ Microsoft Shared \ Ink \ Microsoft.Ink.dll
显然我并不是唯一一个在查找DLL时遇到问题的人,因为有很多关于如何获取它的谷歌条目 - 很多都是错误的,大多数都不是这么简单。
如果您刚刚开始使用签名捕获,请记住向控件添加背景图像,否则它将在此行中失败:
使用bmp =新位图(InkPicture1.BackgroundImage)