位图保存在.Net中是否以不正确的格式保存图像?

时间:2009-08-28 15:13:48

标签: c# .net png bitmap jpeg

我们有一段代码可以将.Net System.Drawing.Bitmap保存到文件中。 Save调用指定文件位置以及我们期望将图像数据保存为Jpeg的ImageFormat,因此输出代码如下所示:

public MediaFile IngestImage(System.Drawing.Bitmap imgSrc, string name){
     ... // left out because it is not relevant to this question
     imgSrc.Save(fullPath, System.Drawing.Imaging.ImageFormat.Jpeg);
     ... // left out because it is not relevant to this question
}

出于某种原因,此方法偶尔会将PNG图像生成为.jpg文件。大多数时候这不是什么大问题,但是项目的另一部分存在问题,这些文件不是真正的jpeg(Windows Media Services)。

感谢任何帮助,有没有人见过这个?

注意: 完整路径就像“\ servcer \ share \ file.jpg”。我们正在使用扩展名“jpg”保存jpg。因此问题......后来我们在Windows Media Server上创建发布点来播放SMIL播放列表,然后我们必须在发布点开始播放时“宣布”文件和格式到发布点它需要一个Jpg文件,因为那样是文件的扩展名,内容实际上是PNG

以下是创建BitpMap对象的实际代码,该对象将传递给上述方法...

        public static Bitmap CreateBitmap(string text, int height, int width, Color foregroundColor, Color backgroundColor, string fontName, int fontSize, bool antialias)
    {
        // Initialize graphics
        Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            if (antialias)
            {
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.TextRenderingHint = TextRenderingHint.AntiAlias;
            }

            // Set colors
            SolidBrush fgBrush = new SolidBrush(foregroundColor);
            SolidBrush bgBrush = new SolidBrush(backgroundColor);

            // paint background
            RectangleF rectF = new RectangleF(0, 0, width, height);
            g.FillRectangle(bgBrush, rectF);

            // Load font
            FontFamily fontFamily = FontFamily.GenericSerif;
            Font font = new Font(fontFamily, fontSize, FontStyle.Regular, GraphicsUnit.Pixel);
            try
            {
                fontFamily = new FontFamily(fontName);
                font = new Font(fontFamily, fontSize, FontStyle.Regular, GraphicsUnit.Pixel);
            }
            catch { }

            // Set font direction & alignment
            StringFormat format = new StringFormat();
            format.Alignment = StringAlignment.Center;
            format.LineAlignment = StringAlignment.Center;

            // Finally, draw the text
            g.DrawString(text, font, fgBrush, rectF, format);

            return bmp;
        }
    }

8 个答案:

答案 0 :(得分:3)

我会通过以下方式解决这个问题:

  1. 削减CreateBitmap()。例如,如果您删除除调用newreturn行的行之外的所有内容,是否会出现问题?我认为它会,但值得检查。如果奇怪的是,此修改会使问题消失,请使用binary search查看是否可以将其追踪到特定行。

  2. 使用Save / try打包catch来查看某个ExternalException是否正在被静默吃掉。 Bitmap.Save()(继承自Image.Save())说明以下关于ExternalException

  3.   

    图片保存错误   图像格式。

         

    -OR -

         

    图像已保存到同一文件中   它是从。

    创建的

    有可能失败的文件已经存在于fullPath的PNG格式且带有.jpg扩展名吗?

答案 1 :(得分:2)

我在裁剪应用程序中也遇到了这个问题。 源图像文件是JPG。 我尝试了几种不同的ImageFormat类型,并且在所有情况下保存的格式都是带有JPG文件扩展名的PNG。 Photoshop然后抱怨'无效的JPEG标记类型'。 如果我将文件重命名为.png,则可以在Photoshop中打开。

使用不同的图像尝试使用JPG扩展名生成正确的JPG格式。

我怀疑原始文件的格式可能是罪魁祸首。 当这个问题得到解决时,我会发布我的发现。

答案 2 :(得分:1)

好吧,我试了一下,试图用上面给出的代码重新解决这个问题。这大致是我做的:

    Random r = new Random();
    for (int i = 0; i < max; i++)
    {
        System.Diagnostics.Debugger.Break()
        int size = 1 + i;
        int width = 1 + i;
        SaveBitmap(@"C:\Projects\test.jpg", ImageFormat.Jpeg, "hello", size, width, Color.Black, Color.White, "Arial", size, true);
        SaveBitmap(@"C:\Projects\test.png", ImageFormat.Jpeg, "hello", size, width, Color.Black, Color.White, "Arial", size, true);
        SaveBitmap(@"C:\Projects\test.jpg", ImageFormat.Jpeg, "hello", size, width, Color.Black, Color.White, "Arial", size, false);
        SaveBitmap(@"C:\Projects\test.png", ImageFormat.Jpeg, "hello", size, width, Color.Black, Color.White, "Arial", size, false);
    }

    public static void SaveBitmap(string filename, ImageFormat format, string text, int height, int width, Color foregroundColor, Color backgroundColor, string fontName, int fontSize, bool antialias)
    {
        using (Image source = CreateBitmap(text, height, width, foregroundColor, backgroundColor, fontName, fontSize, antialias))
            source.Save(filename, format);

        using (Image imgLoaded = Bitmap.FromFile(filename))
        {
            if (imgLoaded.RawFormat.Guid != format.Guid)
                throw new InvalidOperationException();
        }
    }

这样运行没有问题,if(imgLoaded.RawFormat.Guid!= format.Guid)的测试永远不会进入调试器。我猜你有比上面发布的CreateBitmap例程更多的代码。

我的建议:

在调用Image.Save()之后修改代码并在上面的SaveBitmap()中插入验证语句。然后去看看它是如何到达那里的......

答案 3 :(得分:0)

这可能是您或用户指定的文件名的问题。它可能是因为如果以.png结尾,则忽略jpegformat并生成PNG文件。

答案 4 :(得分:0)

您是否尝试过显式设置ImageCodecInfo?

Dim enc = ImageCodecInfo.GetImageEncoders().ToList().Find(Function(e) e.MimeType = "image/png")
objBitMap.Save(stream, enc, params)

答案 5 :(得分:0)

你可以试试这个来保存文件

public bool ResizeImage(string OriginalFilepath, string NewFilepath)
    {
        Bitmap original = (Bitmap)Image.FromFile(OriginalFilepath);
        Bitmap resized = new Bitmap(original, new Size(width,height));
        resized.Save(NewFilepath.jpeg);

    }

答案 6 :(得分:0)

C#Win7(64位)VS 2010 Bitmap.Save(“wnd.bmp”)以png格式保存。 MainWnd是一个C#表单,我捕获并尝试将其保存为文件位图。

        Bitmap bmp = new Bitmap(MainWnd.ActiveForm.Width, MainWnd.ActiveForm.Height);
        Rectangle crec = MainWnd.ActiveForm.ClientRectangle;
        Rectangle r = this.ClientRectangle;
        MainWnd.ActiveForm.DrawToBitmap(bmp, r);
        bmp.Save("wnd.bmp");  // saves as PNG not BMP !!

00000000 89 50 4E 47 0D 0A 1A 0A - 00 00 00 0D 49 48 44 52‰PNG ........ IHDR 00000010 00 00 04 0B 00 00 02 E6 - 08 06 00 00 00 24 30 1D .......æ..... $ 0。 00000020 D1 00 00 00 01 73 52 47 - 42 00 AE CE 1C E9 0000Ñ....sRGB.®... ..

答案 7 :(得分:-1)

看起来你的fullPath可能正在使用png扩展名保存文件,并且你告诉imgSrc使用Jpeg压缩来压缩图像。

我会验证fullPath的扩展名是jpeg或jpg,而不是png。

这是保存时的msdn doc