【问题标题】:thumbnail generation error c#缩略图生成错误 c#
【发布时间】:2011-07-19 23:06:45
【问题描述】:

我正在尝试创建缩略图。我的原始文件夹路径是:假设 I:\my images**,我想将它生成到 **i:\new images。我遇到了两个问题,第一个问题是如果我的图片文件夹包含子文件夹,那么在新图片中它也应该在子文件夹中,而不是作为父文件夹 .

  • 第二次出现错误。**在 GDI+ 中出现一般错误。

    第三次出现此错误:内存不足。**

它是一个 csharp 控制台应用程序

at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(String filename, ImageFormat format)
at ConsoleApplication1.Program.CreateThumbnail(String[] b, Double wid, Double hght, Boolean Isprint)

public void CreateThumbnail(string[] b, double wid, double hght, bool Isprint)
{
    string[] path;
    path = new string [64];
    path = b;
    string saveath = "i:\\check\\a test\\";
    for (int i = 0; i < b.Length; i++)
    {
        DirectoryInfo dir = new DirectoryInfo(path[i]);
        string dir1 = dir.ToString();
        dir1 = dir1.Substring(dir1.LastIndexOf("\\"));

        FileInfo[] files1 = dir.GetFiles();

        foreach (FileInfo f in files1)
        {
            string gh = f.ToString();
            try
            {
                System.Drawing.Image myThumbnail150;
                System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
                System.Drawing.Image imagesize = System.Drawing.Image.FromFile(f.FullName);
                Bitmap bitmapNew = new Bitmap(imagesize);
                double maxWidth = wid;
                double maxHeight = hght;
                int w = imagesize.Width;
                int h = imagesize.Height;
                // Longest and shortest dimension 
                int longestDimension = (w > h) ? w : h;
                int shortestDimension = (w < h) ? w : h;
                // propotionality  
                float factor = ((float)longestDimension) / shortestDimension;
                // default width is greater than height    
                double newWidth = maxWidth;
                double newHeight = maxWidth / factor;
                // if height greater than width recalculate  
                if (w < h)
                {
                    newWidth = maxHeight / factor;
                    newHeight = maxHeight;
                }
                myThumbnail150 = bitmapNew.GetThumbnailImage((int)newWidth, (int)newHeight, myCallback, IntPtr.Zero);

                string ext = Path.GetExtension(f.Name);

                if (!Directory.Exists(saveath + dir1))
                {
                    Directory.CreateDirectory(saveath + dir1);
                    myThumbnail150.Save(saveath + dir1 + "\\" + f.Name.Replace(ext, ".Jpeg"), System.Drawing.Imaging.ImageFormat.Jpeg);
                }
                else if(Directory.Exists(saveath+dir1))
                {
                    myThumbnail150.Save(saveath + dir1+" \\"+ f.Name.Replace(ext, ".Jpeg"), System.Drawing.Imaging.ImageFormat.Jpeg);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("something went wrong" + ex.ToString());
            }
        }
    }
}

【问题讨论】:

  • 您在哪里得到异常 2 和 3?我记得在使用 SQL Server Reporting Services 构建充满图像的报告时遇到了这些异常。在进程尝试在 32 位 Windows 安装上消耗超过 2gb 的内存后触发的异常。请记住,进程受限于它们可以寻址的内存量(无论您的计算机中实际拥有多少内存)。此外,您可能想研究如何处理您的 GDI 对象。我之前使用过非托管 GDI+,您需要在使用对象后进行清理。
  • @Ernriquein 在处理某些文件后出现这些错误,假设该文件夹包含 30 张图像,在处理 17 张图像后会出现此错误。我安装了 64 位 Windows 7。

标签: c#


【解决方案1】:

我刚刚重构了一点代码,现在它可以工作了(在我的机器上):

private static void CreateThumbnail(string[] b, double wid, double hght, bool Isprint)
{
    string saveAt = "D:\\check";
    foreach (string path in b)
    {
        var directory = new DirectoryInfo(path);
        string outputPath = Path.Combine(saveAt, directory.Name);
        foreach (FileInfo f in directory.GetFiles("*.*", SearchOption.AllDirectories))
        {
            if (f.DirectoryName != directory.FullName)
            {
                outputPath = Path.Combine(saveAt, directory.Name, f.Directory.Name);
            }
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            using (Image imagesize = Image.FromFile(f.FullName))
            using (Bitmap bitmapNew = new Bitmap(imagesize))
            {
                double maxWidth = wid;
                double maxHeight = hght;
                int w = imagesize.Width;
                int h = imagesize.Height;
                // Longest and shortest dimension 
                int longestDimension = (w > h) ? w : h;
                int shortestDimension = (w < h) ? w : h;
                // propotionality  
                float factor = ((float)longestDimension) / shortestDimension;
                // default width is greater than height    
                double newWidth = maxWidth;
                double newHeight = maxWidth / factor;
                // if height greater than width recalculate  
                if (w < h)
                {
                    newWidth = maxHeight / factor;
                    newHeight = maxHeight;
                }

                string fileName = Path.Combine(outputPath, Path.GetFileNameWithoutExtension(f.Name) + ".jpeg");
                bitmapNew.GetThumbnailImage((int)newWidth, (int)newHeight, () => false, IntPtr.Zero)
                    .Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
        }
    }
}

我不得不对你的旧代码说几句话:

  • 尽可能使用foreach
  • 避免前三行,它们没用;
  • 避免未使用的变量;
  • 尽可能保持代码整洁;

【讨论】:

  • @As-CII 非常感谢,我现在就试试,它是否也解决了子文件夹问题?
  • @AS-CII Bitmap bitmapNew = new Bitmap(imagesize); 此行内存不足。
  • 我已经对一些图像进行了测试,效果很好。你的图片有多重?
  • @AS-CII 270 MB,但它可能会有所不同,它可以是 1 Gb,但我现在正在 270 MB 上测试它
  • 使用“using”语句来处理是我在使用 GDI+ 对象后清理的其他评论的意思。擅长 AS-CII,因为它提供了代码的重构版本来推动这一点。
【解决方案2】:

关于“GDI+ 通用错误”和“内存不足”异常,您应该查看 SO 上的链接:What is the "best" way to create a thumbnail using ASP.NET?

您必须使用 C# using 语句确保尽快释放 .NET 表面下的非托管 GDI+ 资源以避免内存不足错误。

如果图像无法转换,则可能会发生 GDI+ 泛型。

【讨论】:

  • 谢谢,我会看的:)
猜你喜欢
  • 2016-05-03
  • 2012-07-20
  • 2019-05-08
  • 2016-04-09
  • 2010-11-26
  • 2013-11-23
  • 1970-01-01
  • 2018-10-28
  • 1970-01-01
相关资源
最近更新 更多