GDI+ / C#:如何将图像保存为 EMF?
如果您使用 Image.Save 方法将图像保存到 EMF/WMF,则会出现异常 (http://msdn.microsoft.com/en-us/library/ktx83wah.aspx)
是否有其他方法将图像保存到 EMF/WMF? 有可用的编码器吗?
If you use Image.Save Method to save an image to a EMF/WMF, you get an exception (http://msdn.microsoft.com/en-us/library/ktx83wah.aspx)
Is there another way to save the image to an EMF/WMF?
Are there any encoders available?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
Image
是一个抽象类:您想要执行的操作取决于您处理的是Metafile
还是Bitmap
。使用
Metafile
使用 GDI+ 创建图像并将其保存为 EMF 非常简单。 根据 Mike 的帖子:这是大多数时候你想做的就是 EMF 的用途:以 GDI+ 绘图命令的形式保存矢量图像。
您可以使用上述方法并调用 ig.DrawImage(your_bitmap) 将位图保存到 EMF 文件,但请注意,这不会神奇地将光栅数据转换为矢量图像。
Image
is an abstract class: what you want to do depends on whether you are dealing with aMetafile
or aBitmap
.Creating an image with GDI+ and saving it as an EMF is simple with
Metafile
. Per Mike's post:This is what you want to do most of the time, since that is what EMF is for: saving vector images in the form of GDI+ drawing commands.
You can save a
Bitmap
to an EMF file by using the above method and callingig.DrawImage(your_bitmap)
, but be aware that this does not magically covert your raster data into a vector image.如果我没记错的话,它可以通过 Metafile.GetHenhmetafile()、API GetEnhMetaFileBits() 和 Stream.Write() 的组合来完成,就像
我认为这就是我解决问题时的方法。
If I remember correctly, it can be done with a combination of the Metafile.GetHenhmetafile(), the API GetEnhMetaFileBits() and Stream.Write(), something like
I think this is how I solved the problem when I had it.
图元文件是记录 GDI 操作序列的文件。 它是可缩放的,因为生成图片的原始操作序列被捕获,因此可以缩放记录的坐标。
我认为,在 .NET 中,您应该创建一个
Metafile
对象,使用Graphics.FromImage
创建一个Graphics
对象,然后执行绘图步骤。 当您在文件上绘图时,该文件会自动更新。 您可以在图形文档中找到一个小示例。添加元文件注释。如果您确实想在图元文件中存储位图,请使用以下步骤,然后使用 Graphics.DrawImage 绘制位图。 但是,当缩放时,它将使用
StretchBlt
进行拉伸。A metafile is a file which records a sequence of GDI operations. It is scalable because the original sequence of operations that generated the picture are captured, and therefore the co-ordinates that were recorded can be scaled.
I think, in .NET, that you should create a
Metafile
object, create aGraphics
object usingGraphics.FromImage
, then perform your drawing steps. The file is automatically updated as you draw on it. You can find a small sample in the documentation for Graphics.AddMetafileComment.If you really want to store a bitmap in a metafile, use these steps then use
Graphics.DrawImage
to paint the bitmap. However, when it is scaled it will be stretched usingStretchBlt
.问题是:“是否有其他方法将图像保存到 EMF/WMF?” 不是“什么是图元文件”或“如何创建图元文件”或“如何将图元文件与图形一起使用”。
我也在寻找这个问题的答案“如何保存 EMF/WMF”
事实上,如果您使用:
在这两种情况下,图像都会保存为 png 格式。 这是我无法解决的问题:/
The question was: "Is there another way to save the image to an EMF/WMF?" Not "what is metafile" or "how to create metafile" or "how to use metafile with Graphics".
I also look for answer for this question "how to save EMF/WMF"
In fact if you use:
In both cases image is saved as format png. And this is the problem which I cannot solve :/
erikkallen 的答案是正确的。 我在 VB.NET 中尝试过此操作,并且必须使用 2 个不同的 DllImports 才能使其正常工作:
第一个导入用于第一次调用以获取 emf 大小。 第二次导入以获取实际位。
或者,您可以使用:
这会将 emf 位直接复制到指定文件中。
The answer by erikkallen is correct. I tried this from VB.NET, and had to use 2 different DllImports to get it to work:
The first import is used for the first call to get the emf size. The second import to get the actual bits.
Alternatively you could use:
This copies the emf bits directly to the named file.
您还需要关闭 CopyEnhMetaFile 处理程序:
否则,您无法删除该文件,因为该文件仍在被进程使用。
You also need to close the
CopyEnhMetaFile
handler:Otherwise, you cannot delete the file because it's still used by the process.
我正在寻找一种将图元文件对象中的 GDI 指令保存到 EMF 文件的方法。 韩老师的帖子帮我解决了这个问题。 这是我加入 SOF 之前的事。 谢谢你,韩。 这是我尝试过的。
I was looking for a way to save the GDI instructions in a Metafile object to a EMF file. Han's post helped me solve the problem. This was before I joined SOF. Thank you, Han. Here is what I tried.
我建议避免在托管 .NET 应用程序中出现此类外部和非托管的问题。
相反,我建议更像此线程中给出的托管解决方案:
使用 .NET 将图像转换为 WMF?
PS 我正在回答这个旧线程,因为这是我找到的最佳答案,但最终开发了一个托管解决方案,然后引导我到上面的链接。 所以,为了节省其他人的时间,我想我应该把这个指向那个。
I would recommend avoiding such extern's and unmanaged cruft in a managed .NET app.
Instead, I'd recommend something a bit more like the managed solution given in this thread:
Convert an image into WMF with .NET?
P.S. I am answering this old thread because this was the best answer I had found, but then ended up developing a managed solution, which then lead me to the link above. So, to save others that time, I figured I'd point this one to that one.
看来矢量与位图之间存在很多混淆。 该线程中的所有代码都会生成位图(非矢量)文件 - 它不保留矢量 GDI 调用。 要向自己证明这一点,请下载“EMF Parser”工具并检查输出文件:http: //downloads.zdnet.com/abstract.aspx?docid=749645。
这个问题引起了很多开发者的苦恼。 如果微软能解决这个问题并正确支持他们自己的 EMF 格式,那就太好了。
It appears there is much confusion over vector vs. bitmap. All of the code in this thread generates bitmap (non-vector) files - it does not preserve the vector GDI calls. To prove this to yourself, download the "EMF Parser" tool and inspect the output files: http://downloads.zdnet.com/abstract.aspx?docid=749645.
This issue has caused many developers considering anguish. Sure would be nice if Microsoft would fix this and properly support their own EMF format.
这是一个公共 EMF 类,用于将位图保存为 EMF,但不幸的是,不起作用..返回错误。
This is a public EMF class to save bitmap as EMF, but unfortunally, don't work .. return an error.