生成缩略图时内存不足

paigudw 2008-11-16 02:07:46

windows应用程序 代码如下 本来是要写成windows服务的
先用应用程序测试一下。
大概是写一个文件夹监控程序,一旦文件夹中有图片类文件操作,则在另一个文件夹的对应路径下生成此图的缩略图。
问题:在调试的时候,不会报错,功能全部都有。
但是,在执行的时候,只要在监视的图片中拷贝一张图片进去,就会报错,提示内存不足。

虚心请教原因。
补充:生成缩略图的方法是网上找的,还换过方法,都是一样的症状。
开发环境 vs2008 sp1
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Imaging;
using System.Threading;

namespace WindowsTest
{
public partial class entry : Form
{
public entry()
{
InitializeComponent();
}
#region 按钮事件
/// <summary>
/// 退出应用程序
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonExit_Click(object sender, EventArgs e)
{
Application.Exit();//退出应用程序
}
/// <summary>
/// 选择原路径
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSearchOld_Click(object sender, EventArgs e)
{
this.folderBrowserDialogOldPatch.ShowNewFolderButton = true;
this.folderBrowserDialogOldPatch.ShowDialog();
this.textBoxOldPath.Text = this.folderBrowserDialogOldPatch.SelectedPath;
}
/// <summary>
/// 选择新路径
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSearchNew_Click(object sender, EventArgs e)
{
this.folderBrowserDialogOldPatch.ShowNewFolderButton = true;
this.folderBrowserDialogNewPath.ShowDialog();
this.textBoxNewPath.Text = this.folderBrowserDialogNewPath.SelectedPath;
}
/// <summary>
/// 开始监控原文件夹
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonAutoWatcher_Click(object sender, EventArgs e)
{
if (this.textBoxNewPath.Text.Trim() == string.Empty)
{
MessageBox.Show("请选择目标路径", "错误:目标路径为空", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (this.textBoxOldPath.Text.Trim() == string.Empty)
{
MessageBox.Show("请选择原路径", "错误:原路径为空", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (this.buttonAutoWatcher.Text == "自动")
{
this.buttonAutoWatcher.Text = "停止";
this.SetEnable(false);
this.StartWatcher();
}
else
{
this.buttonAutoWatcher.Text = "自动";
this.SetEnable(true);
}
}
#endregion

#region 自定义方法
/// <summary>
/// 设定按钮的是否可用
/// </summary>
/// <param name="s">是否可用</param>
private void SetEnable(bool s)
{
this.buttonSearchNew.Enabled = s;
this.buttonSearchOld.Enabled = s;
this.textBoxNewPath.Enabled = s;
this.textBoxOldPath.Enabled = s;
this.checkBoxIncludeSub.Enabled = s;
}
private void StartWatcher()
{
fw.BeginInit();
fw.IncludeSubdirectories = this.checkBoxIncludeSub.Checked;//是否包含子文件夹
fw.Path = this.textBoxOldPath.Text;
fw.Changed += new System.IO.FileSystemEventHandler(OnChanged);
fw.Created += new System.IO.FileSystemEventHandler(OnCreated);
fw.Renamed += new System.IO.RenamedEventHandler(OnRenamed);
fw.Deleted += new System.IO.FileSystemEventHandler(OnDeleted);
fw.EnableRaisingEvents = true;
fw.EndInit();
}

void OnDeleted(object sender, System.IO.FileSystemEventArgs e)
{
}

void OnRenamed(object sender, System.IO.RenamedEventArgs e)
{
}

void OnCreated(object sender, System.IO.FileSystemEventArgs e)
{
string NewPath = e.FullPath;
NewPath = NewPath.Replace(this.textBoxOldPath.Text.Trim(), this.textBoxNewPath.Text);
this.CreateFile(e.FullPath, NewPath);
}

void OnChanged(object sender, System.IO.FileSystemEventArgs e)
{
}

/// <summary>
/// 生成新的文件
/// </summary>
/// <param name="ol">原图片路径</param>
/// <param name="ne">新图片路径</param>
/// <returns></returns>
private void CreateFile(string ol, string ne)
{
if (File.Exists(ol))
{
if (!Directory.Exists(ne.Substring(0, ne.LastIndexOf('\\'))))
{
Directory.CreateDirectory(ne.Substring(0, ne.LastIndexOf('\\')));
}
string exFileName= ol.Substring(ol.LastIndexOf('.')).ToLower();
if (exFileName == ".jpg" || exFileName == ".gif" || exFileName == ".bmp"||exFileName==".jpeg"||exFileName==".png")
{
this.ShowThumbnail(ol, ne,Convert.ToInt32(numericUpDownHeight.Value),Convert.ToInt32(numericUpDownWidth.Value));
}
}
}
public void ShowThumbnail(string oldfile, string newfile, int h, int w)
{

System.Drawing.Image img = System.Drawing.Image.FromFile(oldfile);
System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);

int oldh = img.Height;
int oldw = img.Width;

int newh, neww;

double h1 = oldh * 1.0 / h;
double w1 = oldw * 1.0 / w;

double f = (h1 > w1) ? h1 : w1;

if (f < 1.0)
{
newh = oldh;
neww = oldw;
}
else
{
newh = (int)(oldh / f);
neww = (int)(oldw / f);
}

System.Drawing.Image myThumbnail = img.GetThumbnailImage(neww, newh, myCallback, IntPtr.Zero);
string exFileName = oldfile.Substring(oldfile.LastIndexOf('.')+1).ToLower();
switch (exFileName)
{
case "jpg":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
case "bmp":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Bmp);
break;
case "jpeg":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
case "gif":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Gif);
break;
case "png":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Png);
break;
default:
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
}

img.Dispose();
myThumbnail.Dispose();
}
private static bool ThumbnailCallback()
{
return false;
}

#endregion
}
}


...全文
373 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
a79361360 2009-04-18
  • 打赏
  • 举报
回复
4楼这会兄台,遇到你这种情况,有什么好的解决方法呀!?
pojianbing 2008-11-17
  • 打赏
  • 举报
回复
按你的试了下,好像还是有问题,报错 System.IO.IOException文件"D:\pic\Creek.jpg"正在由另一进程使用,因此该进程无法访问该文件。
paigudw 2008-11-16
  • 打赏
  • 举报
回复
嘿嘿 找到解决方法了!
先用文件流处理一下 然后再使用就ok了!
/// <summary>
/// 生成缩略图
/// </summary>
/// <param name="oldfile">原文件完整路径</param>
/// <param name="newfile">目标文件完整路径</param>
/// <param name="h">缩放后的最大高度</param>
/// <param name="w">缩放后的最大宽度</param>
/// <returns></returns>
public bool ShowThumbnail(string oldfile, string newfile, int h, int w)
{
lock (lockObj)
{
FileStream fss = new FileStream(oldfile, FileMode.Open);
System.Drawing.Image img = System.Drawing.Image.FromStream(fss);
System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);

#region 计算高度,宽度
int oldh = img.Height;
int oldw = img.Width;

int newh, neww;

double h1 = oldh * 1.0 / h;
double w1 = oldw * 1.0 / w;

double f = (h1 > w1) ? h1 : w1;

if (f < 1.0)
{
newh = oldh;
neww = oldw;
}
else
{
newh = (int)(oldh / f);
neww = (int)(oldw / f);
}
#endregion
System.Drawing.Image myThumbnail = img.GetThumbnailImage(neww, newh, myCallback, IntPtr.Zero);
string exFileName = oldfile.Substring(oldfile.LastIndexOf('.') + 1).ToLower();
switch (exFileName)
{
case "jpg":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
case "bmp":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Bmp);
break;
case "jpeg":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
case "gif":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Gif);
break;
case "png":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Png);
break;
default:
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
}
fss.Close();
fss.Dispose();
img.Dispose();
myThumbnail.Dispose();
return true;
}
}
private static bool ThumbnailCallback()
{
return false;
}
pojianbing 2008-11-16
  • 打赏
  • 举报
回复
那就不知道啦,等待强人出现。
paigudw 2008-11-16
  • 打赏
  • 举报
回复
额。。。
我用的是3.5的嘛。。。
还3.5sp1。。。。
pojianbing 2008-11-16
  • 打赏
  • 举报
回复
我猜测是vista在jpg图片中添加了额外的信息,如分级(就是在vista上看到的星星),导致.net framework 2.0的System.Drawing.Image.FromFile认为图片格式有问题,从而出现上边的错。我想用.net framework 3.0的类应该没问。 不过这都是我乱猜的,等待高手出现啦。
paigudw 2008-11-16
  • 打赏
  • 举报
回复
果然如彼。。。。
这是怎么回事呢?能解释一下嘛?
谢谢!!
pojianbing 2008-11-16
  • 打赏
  • 举报
回复
你把vista示例图片的属性惹得祸,你点击图片右键选择属性-详细信息-删除属性和个人信息,然后会生成一个图片的副本,你把那个副本拷过去就没问题。
pojianbing 2008-11-16
  • 打赏
  • 举报
回复
我用其它图片没问题,用vista的示例图片就有问题。很奇怪。
paigudw 2008-11-16
  • 打赏
  • 举报
回复
还是报错呢?
我用的是vista的示例图片 应该不会有问题吧 而且我只拷贝了一张
paigudw 2008-11-16
  • 打赏
  • 举报
回复
谢谢 等我马上试试看
wangkuang5 2008-11-16
  • 打赏
  • 举报
回复
img.Dispose();
加一句
img=null; 感觉有效一些
wangkuang5 2008-11-16
  • 打赏
  • 举报
回复
System.Drawing.Image img = System.Drawing.Image.FromFile(oldfile);
这句常会报内存不足的错误,特别是图片本身不能被正确识别,或是文件已经损坏,以及5M以上的超高清的图片,
我常用Backgroundworker来处理这些事情
pojianbing 2008-11-16
  • 打赏
  • 举报
回复
我按你的测试只有在一次拷贝很多图片时才会出现内存不足的情况,这个问题可以通过上边加锁的方式解决。至于你的加载一个图片就报错的情况,可能是你的图片太大。
pojianbing 2008-11-16
  • 打赏
  • 举报
回复
试试加锁。


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Imaging;
using System.Threading;

namespace WindowsTest
{
public partial class entry : Form
{
private static Object lockObj = new object();

public entry()
{
InitializeComponent();
}
#region 按钮事件
/// <summary>
/// 退出应用程序
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonExit_Click(object sender, EventArgs e)
{
Application.Exit();//退出应用程序
}
/// <summary>
/// 选择原路径
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSearchOld_Click(object sender, EventArgs e)
{
this.folderBrowserDialogOldPatch.ShowNewFolderButton = true;
this.folderBrowserDialogOldPatch.ShowDialog();
this.textBoxOldPath.Text = this.folderBrowserDialogOldPatch.SelectedPath;
}
/// <summary>
/// 选择新路径
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSearchNew_Click(object sender, EventArgs e)
{
this.folderBrowserDialogOldPatch.ShowNewFolderButton = true;
this.folderBrowserDialogNewPath.ShowDialog();
this.textBoxNewPath.Text = this.folderBrowserDialogNewPath.SelectedPath;
}
/// <summary>
/// 开始监控原文件夹
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonAutoWatcher_Click(object sender, EventArgs e)
{
if (this.textBoxNewPath.Text.Trim() == string.Empty)
{
MessageBox.Show("请选择目标路径", "错误:目标路径为空", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (this.textBoxOldPath.Text.Trim() == string.Empty)
{
MessageBox.Show("请选择原路径", "错误:原路径为空", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (this.buttonAutoWatcher.Text == "自动")
{
this.buttonAutoWatcher.Text = "停止";
this.SetEnable(false);
this.StartWatcher();
}
else
{
this.buttonAutoWatcher.Text = "自动";
this.SetEnable(true);
}
}
#endregion

#region 自定义方法
/// <summary>
/// 设定按钮的是否可用
/// </summary>
/// <param name="s">是否可用</param>
private void SetEnable(bool s)
{
this.buttonSearchNew.Enabled = s;
this.buttonSearchOld.Enabled = s;
this.textBoxNewPath.Enabled = s;
this.textBoxOldPath.Enabled = s;
this.checkBoxIncludeSub.Enabled = s;
}
private void StartWatcher()
{
fw.BeginInit();
fw.IncludeSubdirectories = this.checkBoxIncludeSub.Checked;//是否包含子文件夹
fw.Path = this.textBoxOldPath.Text;
fw.Changed += new System.IO.FileSystemEventHandler(OnChanged);
fw.Created += new System.IO.FileSystemEventHandler(OnCreated);
fw.Renamed += new System.IO.RenamedEventHandler(OnRenamed);
fw.Deleted += new System.IO.FileSystemEventHandler(OnDeleted);
fw.EnableRaisingEvents = true;
fw.EndInit();
}

void OnDeleted(object sender, System.IO.FileSystemEventArgs e)
{
}

void OnRenamed(object sender, System.IO.RenamedEventArgs e)
{
}

void OnCreated(object sender, System.IO.FileSystemEventArgs e)
{
string NewPath = e.FullPath;
NewPath = NewPath.Replace(this.textBoxOldPath.Text.Trim(), this.textBoxNewPath.Text);
this.CreateFile(e.FullPath, NewPath);
}

void OnChanged(object sender, System.IO.FileSystemEventArgs e)
{
}

/// <summary>
/// 生成新的文件
/// </summary>
/// <param name="ol">原图片路径</param>
/// <param name="ne">新图片路径</param>
/// <returns></returns>
private void CreateFile(string ol, string ne)
{
if (File.Exists(ol))
{
if (!Directory.Exists(ne.Substring(0, ne.LastIndexOf('\\'))))
{
Directory.CreateDirectory(ne.Substring(0, ne.LastIndexOf('\\')));
}
string exFileName= ol.Substring(ol.LastIndexOf('.')).ToLower();
if (exFileName == ".jpg" || exFileName == ".gif" || exFileName == ".bmp"||exFileName==".jpeg"||exFileName==".png")
{
this.ShowThumbnail(ol, ne,Convert.ToInt32(numericUpDownHeight.Value),Convert.ToInt32(numericUpDownWidth.Value));
}
}
}
public void ShowThumbnail(string oldfile, string newfile, int h, int w)
{
lock (lockObj)
{
System.Drawing.Image img = System.Drawing.Image.FromFile(oldfile);
System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);

int oldh = img.Height;
int oldw = img.Width;

int newh, neww;

double h1 = oldh * 1.0 / h;
double w1 = oldw * 1.0 / w;

double f = (h1 > w1) ? h1 : w1;

if (f < 1.0)
{
newh = oldh;
neww = oldw;
}
else
{
newh = (int)(oldh / f);
neww = (int)(oldw / f);
}

System.Drawing.Image myThumbnail = img.GetThumbnailImage(neww, newh, myCallback, IntPtr.Zero);
string exFileName = oldfile.Substring(oldfile.LastIndexOf('.')+1).ToLower();
switch (exFileName)
{
case "jpg":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
case "bmp":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Bmp);
break;
case "jpeg":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
case "gif":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Gif);
break;
case "png":
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Png);
break;
default:
myThumbnail.Save(newfile, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
}

img.Dispose();
myThumbnail.Dispose();
}
}
private static bool ThumbnailCallback()
{
return false;
}

#endregion
}
}

mjjzg 2008-11-16
  • 打赏
  • 举报
回复
UP

111,094

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧