0

我知道标准 WMF 文件使用 18 字节的标头,后跟 GDI 命令记录。一个简单的网络搜索告诉我:“还有两个额外的 WMF 变体,它们在标准标题前面放置另一个标题。可放置的元文件使用包含 xy 坐标的 22 字节标题来定位页面上的图像”。但是对于这种元文件类型,我有点没有人手不足?与标准 WMF 相比,这种类型应该解决什么样的要求?我为什么感兴趣?我有以下代码用于重新调整 WMF 的大小并将其转换为 GIF,它在尝试从 META 文件中构造位图时失败:

    public Stream Resize(string filePath, int maxSize)
    {
        try
        {
            MemoryStream stream = new MemoryStream();

            using (Metafile img = new Metafile(filePath))
            {
                MetafileHeader header = img.GetMetafileHeader();
                float scale = header.DpiX / 96f;

                var newSize = CalcaulateSize(img.Width, img.Height, maxSize);

                using (Bitmap bitmap = new Bitmap((int)(scale * img.Width / header.DpiX * 100), (int)(scale * img.Height / header.DpiY * 100)))
                {
                    using (Graphics g = Graphics.FromImage(bitmap))
                    {
                        g.Clear(Color.White);
                        g.ScaleTransform(scale, scale);
                        g.DrawImage(img, 0, 0);
                    }

                    var resizedBitmap = new Bitmap(newSize.Width, newSize.Height);

                    using (var g2 = Graphics.FromImage(resizedBitmap))
                    {
                        g2.CompositingQuality = CompositingQuality.HighQuality;
                        g2.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        g2.SmoothingMode = SmoothingMode.AntiAlias;
                        g2.PixelOffsetMode = PixelOffsetMode.HighQuality;
                        g2.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
                        g2.TextContrast = 12;
                        g2.Clear(Color.White);
                        g2.DrawImage(bitmap, 0, 0, newSize.Width, newSize.Height);
                    }

                    resizedBitmap.Save(stream, ImageFormat.Gif);
                }

                stream.Position = 0;
            }

            return stream;
        }
        catch (Exception)
        {
            return null;
        }

并引发异常“参数无效”。

(int)(scale * img.Width / header.DpiX * 100) = 22181 (int)(scale * img.Height / header.DpiY * 100)) = 33718

[为单个位图一次分配太多内存,导致立即异常]

您将如何更改附加代码以重新调整大小并转换可放置的元文件?

4

1 回答 1

0

我怀疑您的尺寸计算已关闭。

查看我的 C++ 代码,我根据增强的图元文件标头中的信息进行此计算,其中 hEMF 是图元文件的句柄。然后,我们使用 Graphics 使用这些尺寸将图像直接绘制到屏幕上。

希望这个或MSDN 链接能有所帮助。抱歉,还不够完整。

        ENHMETAHEADER emh;
    UINT nBytes = ::GetEnhMetaFileHeader(hEMF, sizeof(ENHMETAHEADER), &emh);
    if (nBytes != 0) {
        RECT rect{ // Based on info from http://support.microsoft.com/kb/230675
            (int) ((float) (emh.rclFrame.left) * emh.szlDevice.cx / (emh.szlMillimeters.cx*100.0f)),    // Left
            (int) ((float) (emh.rclFrame.top) * emh.szlDevice.cy / (emh.szlMillimeters.cy*100.0f)),     // Top
            (int) ((float) (emh.rclFrame.right) * emh.szlDevice.cx / (emh.szlMillimeters.cx*100.0f)),   // Right
            (int) ((float) (emh.rclFrame.bottom) * emh.szlDevice.cy / (emh.szlMillimeters.cy*100.0f))   // Bottom
        };
        bounds.x = abs(rect.right - rect.left);
        bounds.y = abs(rect.bottom - rect.top);
于 2014-04-17T14:25:50.297 回答