[英]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;
}
}
我通过以下方式解决这个问题:
削减CreateBitmap()
。 例如,如果删除除调用new
和return
行的行之外的所有内容,是否会出现问题? 我认为它会,但值得检查。 如果在奇怪的情况下问题随着此修改而消失,则使用二进制搜索来查看是否可以将其跟踪到特定行。
使用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.