繁体   English   中英

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

[英]Bitmap Save in .Net is saving the image in an incorrect format?

我们有一段代码将.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;
        }
    }

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

  1. 削减CreateBitmap() 例如,如果删除除调用newreturn行的行之外的所有内容,是否会出现问题? 我认为它会,但值得检查。 如果在奇怪的情况下问题随着此修改而消失,则使用二进制搜索来查看是否可以将其跟踪到特定行。

  2. 使用try / catch包装Save调用以查看某个地方是否正在静默地使用ExternalException Bitmap.Save() (继承自Image.Save() )说下面的ExternalException

图像以错误的图像格式保存。

-要么-

图像已保存到创建它的同一文件中。

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

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

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

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

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

    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()中插入验证语句。 然后去看看它是如何到达那里的......

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

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

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);

    }

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

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

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.®... ..

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

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

这是Save上的msdn doc

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM