.net - 使用 .NET 将图像转换为 WMF?

标签 .net image bitmap encode wmf

有很多将 wmf 转换为位图的示例,例如:
Reliable .wmf/wmf to Pixel based image conversion

但我需要反向操作。我不寻找矢量化器。我只想在 wmf 文件中嵌入图片,而不必担心 wmf 格式的位和字节。我需要一个 .NET 的解决方案,最好是在 C# 中。

我首先认为这可以完成这项工作:

using (Image img = Image.FromFile (path)) {
    img.Save (myStream, System.Drawing.Imaging.ImageFormat.Wmf);
}

但这在运行时提示编码器为空。我在哪里/如何构建这样的编码器?我不需要复杂的,只需要一个将图像包装成 wmf 的。 WMF 支持的格式有什么要求吗?我想支持 png 和 bmp 但也支持 gif 吗?

最佳答案

这是该问题的完整答案,包括我的修改。文森特的回答是完全正确的。只有一些定义和一个枚举丢失。这就是为什么我在这里发布“干净”的工作代码,希望它对其他人有用。

        [Flags]
        private enum EmfToWmfBitsFlags {
            EmfToWmfBitsFlagsDefault = 0x00000000,
            EmfToWmfBitsFlagsEmbedEmf = 0x00000001,
            EmfToWmfBitsFlagsIncludePlaceable = 0x00000002,
            EmfToWmfBitsFlagsNoXORClip = 0x00000004
        }

        private static int MM_ISOTROPIC = 7;
        private static int MM_ANISOTROPIC = 8;

        [DllImport ("gdiplus.dll")]
        private static extern uint GdipEmfToWmfBits (IntPtr _hEmf, uint _bufferSize,
            byte[] _buffer, int _mappingMode, EmfToWmfBitsFlags _flags);
        [DllImport ("gdi32.dll")]
        private static extern IntPtr SetMetaFileBitsEx (uint _bufferSize,
            byte[] _buffer);
        [DllImport ("gdi32.dll")]
        private static extern IntPtr CopyMetaFile (IntPtr hWmf,
            string filename);
        [DllImport ("gdi32.dll")]
        private static extern bool DeleteMetaFile (IntPtr hWmf);
        [DllImport ("gdi32.dll")]
        private static extern bool DeleteEnhMetaFile (IntPtr hEmf);

        private static MemoryStream MakeMetafileStream (Bitmap image)
        {
            Metafile metafile = null;
            using (Graphics g = Graphics.FromImage (image)) {
                IntPtr hDC = g.GetHdc ();
                metafile = new Metafile (hDC, EmfType.EmfOnly);
                g.ReleaseHdc (hDC);
            }

            using (Graphics g = Graphics.FromImage (metafile)) {
                g.DrawImage (image, 0, 0);
            }
            IntPtr _hEmf = metafile.GetHenhmetafile ();
            uint _bufferSize = GdipEmfToWmfBits (_hEmf, 0, null, MM_ANISOTROPIC,
                EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
            byte[] _buffer = new byte[_bufferSize];
            GdipEmfToWmfBits (_hEmf, _bufferSize, _buffer, MM_ANISOTROPIC,
                    EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
            IntPtr hmf = SetMetaFileBitsEx (_bufferSize, _buffer);
            string tempfile = Path.GetTempFileName ();
            CopyMetaFile (hmf, tempfile);
            DeleteMetaFile (hmf);
            DeleteEnhMetaFile (_hEmf);

            var stream = new MemoryStream ();
            byte[] data = File.ReadAllBytes (tempfile);
            //File.Delete (tempfile);
            int count = data.Length;
            stream.Write (data, 0, count);
            return stream;
        }

关于.net - 使用 .NET 将图像转换为 WMF?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5270763/

相关文章:

c# - 未选中匿名访问时无法访问该网站

java - 在android中,如何从图像按钮中提取图像?

c# - 从常见图像格式中删除所有元数据?

android - BitmapFactory.decodeFile 即使图像存在也返回 null

html - 如果分辨率很小(或者您稍微调整浏览器大小),标题中的图像会彼此下方

c# - 将 System.Drawing.Bitmap 转换为 WPF 的 System.Windows.Media.BitmapImage

c# - 用于检查字符串数组中唯一性的哈希码

c# - 在进行一些密集计算之前等待多个快速属性更改事件 (C#)

.net - 跨平台 SSO - 从哪里开始?

java - 如何在不继承 Swing 的情况下正确地获取 "layer"图像(并更改源)