使用 .NET 将图像转换为 WMF? [英] Convert an image into WMF with .NET?

查看:20
本文介绍了使用 .NET 将图像转换为 WMF?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有很多将 wmf 转换为位图的示例,例如:可靠的 .wmf/wmf 到基于像素的图像转换>

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

我最初认为这可以完成工作:

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

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

解决方案

来自 此处:

<块引用>

当您使用 Save 方法保存一个作为 Windows 图元文件的图形图像格式 (WMF) 或增强型元文件格式(EMF)文件,生成的文件保存为便携式网络图形 (PNG) 文件代替.这出现行为是因为 GDI+.NET Framework 的组件没有可以使用的编码器将文件另存为 .wmf 或 .emf 文件.

但我想你已经做到了 :)

这里有人将位图放入 FileStream.

metafileStream = MakeMetafileStream(gdiBitmap);

MakeMetafileStream() 为:

private static MemoryStream MakeMetafileStream(Bitmap image){图形图形 = 空;图元文件图元文件=空;var stream = new MemoryStream();尝试{使用 (graphics = Graphics.FromImage(image)){var hdc = graphics.GetHdc();元文件=新元文件(流,hdc);graphics.ReleaseHdc(hdc);}使用 (graphics = Graphics.FromImage(metafile)){ graphics.DrawImage(image, 0, 0);}}最后{如果(图形!= null){ graphics.Dispose();}如果(元文件!= null){ 元文件.处置();}}返回流;}

有趣的东西.但至于编码器的事情...

此处 MS 的 Peter Huang 发布了这种非托管方法:

 [DllImport("gdiplus.dll")]私有静态外部 uint GdipEmfToWmfBits (IntPtr _hEmf, uint _bufferSize,byte[] _buffer, int _mappingMode, EmfToWmfBitsFlags _flags);[DllImport("gdi32.dll")]私有静态外部 IntPtr SetMetaFileBitsEx (uint _bufferSize,字节[] _buffer);[DllImport("gdi32.dll")]private static extern IntPtr CopyMetaFile (IntPtr hWmf,字符串文件名);[DllImport("gdi32.dll")]private static extern bool DeleteMetaFile (IntPtr hWmf);[DllImport("gdi32.dll")]private static extern bool DeleteEnhMetaFile (IntPtr hEmf);private void button4_Click(object sender, System.EventArgs e){图形 g= this.CreateGraphics();IntPtr hDC = g.GetHdc();图元文件 mf = 新图元文件(hDC,EmfType.EmfOnly);g.ReleaseHdc(hDC);g.Dispose();g=Graphics.FromImage(mf);//Pen p = new Pen(Color.White,5);g.DrawArc(Pens.Black,0,0,200,200,0,360);//g.DrawImage(Bitmap.FromFile(@"c:	emp	est.bmp"),0,0);g.Dispose();IntPtr _hEmf= mf.GetHenhmetafile();uint _bufferSize = GdipEmfToWmfBits(_hEmf, 0, null, MM_ANISOTROPIC,EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);字节[] _buffer = 新字节[_bufferSize];GdipEmfToWmfBits(_hEmf, _bufferSize, _buffer, MM_ANISOTROPIC,EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);IntPtr hmf = SetMetaFileBitsEx(_bufferSize, _buffer);CopyMetaFile(hmf, "C:\ConvertedMetafile.wmf");删除元文件(hmf);DeleteEnhMetaFile(_hEmf);}

希望这能让你到达那里:)

There are plenty of examples of converting a wmf into a bitmap like: Reliable .wmf/wmf to Pixel based image conversion

But I need the reverse operation. I do not look for a vectorizer. I just want to embed a picture inside a wmf file without having to bother about the bits and bytes of the wmf format. I need a solution for .NET preferably in C#.

I first thought this would do the job:

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

But this complains at runtime that the encoder is null. Where/How can I build such an encoder? I do not need a complicated one, just one that wraps an image into a wmf. Are there some requirements on the supported formats in WMF? I suppose png and bmp are supported but is gif also supported?

解决方案

From here:

When you use the Save method to save a graphic image as a Windows Metafile Format (WMF) or Enhanced Metafile Format (EMF) file, the resulting file is saved as a Portable Network Graphics (PNG) file instead. This behavior occurs because the GDI+ component of the .NET Framework does not have an encoder that you can use to save files as .wmf or .emf files.

But I guess you already got that far :)

Here someone is putting a bitmap in a FileStream.

metafileStream = MakeMetafileStream(gdiBitmap);

with MakeMetafileStream() being:

private static MemoryStream MakeMetafileStream(Bitmap image)
{
  Graphics graphics = null;
  Metafile metafile= null;
  var stream = new MemoryStream();
  try
  {
    using (graphics = Graphics.FromImage(image))
    {
      var hdc = graphics.GetHdc();
      metafile= new Metafile(stream, hdc);
      graphics.ReleaseHdc(hdc);
    }
    using (graphics = Graphics.FromImage(metafile))
    { graphics.DrawImage(image, 0, 0); }
  }
  finally
  {
    if (graphics != null)
    { graphics.Dispose(); }
    if (metafile!= null)
    { metafile.Dispose(); }
  }
  return stream;
}

Interesting stuff. But as to the encoder thing...

Here Peter Huang from MS posted this unmanaged approach:

        [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 void button4_Click(object sender, System.EventArgs e)
        {
            Graphics g= this.CreateGraphics();
            IntPtr hDC = g.GetHdc();
            Metafile mf = new Metafile(hDC,EmfType.EmfOnly);
            g.ReleaseHdc(hDC);
            g.Dispose();
            g=Graphics.FromImage(mf);
            //Pen p = new Pen(Color.White,5);
            g.DrawArc(Pens.Black,0,0,200,200,0,360);
            //g.DrawImage(Bitmap.FromFile(@"c:	emp	est.bmp"),0,0);
            g.Dispose();
            IntPtr _hEmf= mf.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);
            CopyMetaFile(hmf, "C:\ConvertedMetafile.wmf");
            DeleteMetaFile(hmf);
            DeleteEnhMetaFile(_hEmf);
        }

Hope this'll get you there :)

这篇关于使用 .NET 将图像转换为 WMF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆