位图. [英] Bitmap.Save "Generic Error"

查看:76
本文介绍了位图.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我运行我的应用程序时,我的脸上出现以下错误:"GDI +中发生了一般性错误." 我环顾四周,发现人们有类似的错误,但是没有找到真正的解决方案,否则实施起来实在是一件痛苦的事情.那些还没有解决方案的人还没有发布他们的代码.

When I run my application the following error get's thrown in my face "A generic error occurred in GDI+." I've looked around and seen people have similar errors, but have found no real solution, or it is a real pain in the butt to implement. And those that have not gotten a solution have not posted their code.

因此,我想我也应该尝试一下,然后抛出另一个线程来解决此错误.这是我的代码&错误

So I thought I might as well give it a shot and throw another thread up about how to fix this error. This is my Code & Error

            Random r = new Random();
            DirectoryInfo di = new DirectoryInfo(folderbrowser.SelectedPath);
            FileInfo[] fi = di.GetFiles().Where(f => extensions.Contains(f.Extension.ToLower())).ToArray();
            for (int i = 0; i < imageCount; i++)
            {
                int img1 = r.Next(imageCount);
                int img2 = r.Next(imageCount);
                while (img2 == img1)
                    img2 = r.Next(imageCount);
                pic1.Image = Image.FromFile(fi[img1].FullName);
                pic2.Image = Image.FromFile(fi[img2].FullName);
                Image i1 = pic1.Image;
                Image i2 = pic2.Image;
                Bitmap bitmap = new Bitmap(i1.Width + i2.Width, 1080);
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    g.DrawImage(i1, 0, 0);
                    g.DrawImage(i2, i2.Width, 0);
                }
                bitmap.Save(@"C:\TEST\Image_"+i.ToString());                   
            }

这是错误代码

System.Runtime.InteropServices.ExternalException was unhandled
  Message=A generic error occurred in GDI+.
  Source=System.Drawing
  ErrorCode=-2147467259
  StackTrace:
       at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
       at System.Drawing.Image.Save(String filename, ImageFormat format)
       at System.Drawing.Image.Save(String filename)
       at WallpaperMerger.Form1.btn_merge_Click(Object sender, EventArgs e) in C:\Users\PeppeJ\documents\visual studio 2010\Projects\WallpaperMerger\WallpaperMerger\Form1.cs:line 113
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at WallpaperMerger.Program.Main() in C:\Users\PeppeJ\documents\visual studio 2010\Projects\WallpaperMerger\WallpaperMerger\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

那么,StackOverflow的人们在想些什么.我是和其他人一样的船,必须输入一个荒谬的复杂代码来解决此问题,还是我犯了一个简单的错误并且很容易纠正?

So what do you guys here at StackOverflow think. Am I the same boat as the others and have to type a ridiculously complex code to solve this problem, or have I made a simple mistake and it's easy to correct?

如果您想自己测试一下是否有帮助,请访问调试版本

If you want to test it yourself if that might somehow help, here's a link to the Debug Build

只需勾选使用多个文件",然后选择一个包含图像文件(C:\ Users \ Public \ Pictures \ Sample Pictures)的文件夹.点击合并.

Simply tick "Use Multiple Files", select a folder containing image files (C:\Users\Public\Pictures\Sample Pictures) for instance. Hit Merge.

我想补充一点,我使用Bitmap.Save保存在此函数中,并且可以完美地工作.

I'd like to add that I use Bitmap.Save in this function, and it works flawlessly.

        Bitmap bitmap = new Bitmap(pic1.Image.Width + pic2.Image.Width, 1080);
        using (Graphics g = Graphics.FromImage(bitmap))
        {
            g.DrawImage(pic1.Image, 0, 0);
            g.DrawImage(pic2.Image, pic1.Image.Width, 0);
        }
        if (savepicfile.ShowDialog() == DialogResult.OK)
            bitmap.Save(savepicfile.FileName);

在上述功能文件中,加载方式如下:

In the above function files are loaded like this:

    DialogResult result = pic1file.ShowDialog();
    if (result == DialogResult.OK)
        pic1.Image = Image.FromFile(pic1file.FileName);

值得一提的是"picX"是"System.Windows.Forms.PictureBox"对象.

Something else worth mentioning is that "picX" is a "System.Windows.Forms.PictureBox" object.

推荐答案

以我的经验,此错误有99%的时间是由以下任一原因引起的:

In my experience, 99% of the time this error is caused by an issue where either:

  1. 您无权写入文件.
  2. 您要写入的文件已被另一个进程锁定.

有时,在以下情况下我会遇到它:

Occasionally I've run into it when:

  • 我正在绘制其中包含零点的GraphicPath.
  • 我不是财产处置我的GDI +对象. (可能与上面的选项2有关)

我将首先检查前两件事.如果可以排除这种情况,我可以在您提供的代码中看到您没有正确处置一些对象的位置.我会清理的.如果您未按计划调用Dispose(),则GDI +与.NET的GC并不是特别配合.

I'd check the first two things first. If that can be ruled out I can see where you're not properly disposing of a few objects in the code you provided. I'd clean that up. GDI+ isn't particularly cooperative with .NET's GC if you aren't calling Dispose() when you're supposed to.

        var r = new Random();
        var di = new DirectoryInfo(folderbrowser.SelectedPath);
        var fi = di.GetFiles().Where(f => extensions.Contains(f.Extension.ToLower())).ToArray();
        for (var i = 0; i < imageCount; i++)
        {
            var img1 = r.Next(imageCount);
            var img2 = r.Next(imageCount);
            while (img2 == img1) 
            {
                img2 = r.Next(imageCount);
            }
            pic1.Image = Image.FromFile(fi[img1].FullName);
            pic2.Image = Image.FromFile(fi[img2].FullName);
            var i1 = pic1.Image;
            var i2 = pic2.Image;
            using (var bitmap = new Bitmap(i1.Width + i2.Width, 1080))
            using (var g = Graphics.FromImage(bitmap))
            {
                g.DrawImage(i1, 0, 0);
                g.DrawImage(i2, i2.Width, 0);
                bitmap.Save(@"C:\TEST\Image_"+i.ToString());
            }                   
        }


更多想法(很好,上面数字2的澄清)...

  • 如果您的应用程序中有一个PictureBox或其他控件引用了您要编写的C:\TEST目录中的图像,则您会看到此错误.
  • 如果您有其他代码正在读取要写入的图像,则会看到此错误.
  • 如果外部进程(例如您的IDE,图像查看器/编辑器等)打开了文件,您会看到此错误.
  • If you have a PictureBox or other control in your app referencing the images in your C:\TEST directory that you're trying to write, you can see this error.
  • If you have other code reading the image you're trying to write to you can see this error.
  • If an external process, such as your IDE, an image viewer/editor, etc. has the file open you can see this error.

调试思路:

  • Try setting a break point on the Save call. When you get to it, use the tips found here to figure out what process might be accessing the file: How do I find out which process is locking a file using .NET?
  • Try just deleting the files first to see if it allows you to save if they're not their.
  • Try setting full permissions for "Everyone" on the directory you're writing to (Don't leave it like this, though)
  • Make sure the width of the image you're trying to save is a number greater than zero. I noticed you're setting that programatically.
  • Make sure the width of the image you're trying to save isn't ridiculously huge (an maybe you're running into a memory issue?)

这篇关于位图.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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