`
chhj_292
  • 浏览: 37550 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

递归生成目标文件夹下所有子目录的图片的缩略图文件

阅读更多

昨天发了一帖,无人响应,甚至不知道有没有人仔细研读过那些源代码,伤心中。

 

描述:由于项目发布的新版本中支持图片缩略图,加快了浏览速度,客户反映不错,要求在其已有的特定的文件夹下的图片也生成对应的缩略图(项目运行一年有余,至今在用缩略图策略,汗...),好像没有找到能递归处理所有图片文件的软件,所以自己写了一个能递归的函数处理(也是一种懒惰的手法)。
如果没有设置JVM参数,大概只处理1MB左右的图片文件,但是设置了JVM参数在比较理想的情况下,能处理大约10MB的文件,而且持续处理上千个文件不内存不回又太大的损耗,只是CPU稍有影响
附:Bat文件内容。
说明:版权所有,转载请声明命。

 

/**
 * Copyright 2008 pantosoft. All rights reserved.
 */
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * 针对特定文件夹下的所有子目录图片文件缩略图
 * 		要求:	1.安装好jdk,并且配置好运行环境;
 * 				2.文件小于1mb;
 * 				3.文件后缀为:“jpg,jpeg,gif,bmp”中的一种或几种;
 * 使用方法:1.widows平台下,安装JDK后,直接运行ImageResizer.bat即可。
 * 注意:支持递归生成策略。
 * 
 * @author Cheng 2008-9-22 上午11:26:46
 * @version 1.0.0
 */
public class ImageResizer {
	private static final String	PIC_TEMPORARY	= "_temporary.db";
	private static final String	LOG_FILE_NAME	= "operate.log";
	private static int			successed		= 0;
	private static int			allFiles		= 0;
	private String				dir				= null;
	private StringBuilder		failedFiles		= new StringBuilder();
	private StringBuilder		infomation		= new StringBuilder();

	/**
	 * 构造函数,初始化目标文件夹
	 * @param dir
	 */
	public ImageResizer(String dir) {
		this.dir = dir;
	}

	public void operate(String _path) {
		if (_path == null)
			throw new NullPointerException("您还没有初始化需要操作的文件路径。");
		File file = new File(_path);
		if (!file.exists()) {
			return;
		}
		File[] files = file.listFiles();
		if (files.length >= 10000) {
			write(_path + "目录下文件大于10000个,请分批处理!");
			return;
		} else {
			for (int i = 0; i < files.length; i++) {
				allFiles++;
				if (files[i].isDirectory()) {
					write("处理目录:" + files[i].getAbsolutePath());
					this.operate(files[i].getAbsolutePath());
				} else {
					write("\t处理文件:" + files[i].getName());
					if (files[i].length() > 1000000) {
						write("\t超大:" + files[i].getAbsoluteFile() + "["
								+ files[i].length() + "]字节。");
						failedFiles.append("\t超大:" + files[i].getAbsoluteFile()
								+ "[" + files[i].length() / 1000 + "]字节。\n");
						continue;
					}
					if (files[i].getName().indexOf(".") != -1) {
						//已经是缩略图文件了
						if (files[i].getName().indexOf(PIC_TEMPORARY) != -1)
							continue;
						String ext = files[i].getName().substring(
								files[i].getName().lastIndexOf("."),
								files[i].getName().length()).toLowerCase();
						if (ext.equals(".jpg") || ext.equals(".gif")
								|| ext.equals(".bmp")) {
							write("\t压缩:" + files[i].getName() + "...");
							resize(files[i]);
							write("\t完成:" + files[i].getName() + "");
						}
					} else {
						write("文件类型未知!");
					}
				}
			}
		}
	}

	/**
	 * 输出,方便拓展成log4j,或者其它形式。
	 * @param str
	 */
	public void write(String str) {
		infomation.append("\n").append(str);
	}

	private void flush() {
		if (this.dir == null || this.dir.equals(""))
			throw new NullPointerException(
					"destinate folder is null or its value is empty.");
		File file = null;
		if (file == null || file.exists()) {
			file = new File(this.dir + "/" + LOG_FILE_NAME);
		}
		try {
			OutputStream stream = new FileOutputStream(file, false);
			stream.write((this.infomation.toString()).getBytes());
			if (this.failedFiles.toString().length() != 0) {
				stream.write("\n\n\n--失败文件列表--\n".getBytes());
				stream.write((this.failedFiles.toString()).getBytes());
				stream.write("\n--------------".getBytes());
			}
			stream.flush();
			stream.close();
		} catch (FileNotFoundException ex) {
			// TODO Auto-generated catch block
			ex.printStackTrace();
		} catch (IOException ex) {
			// TODO Auto-generated catch block
			ex.printStackTrace();
		}
	}

	public void resize(File _file) {
		if (_file == null || _file.length() == 0) {
			throw new NullPointerException("目标文件错误!");
		}
		ImageUtils imageUtils = null;
		try {
			imageUtils = new ImageUtils(_file);
			imageUtils.resize(160, 140);

		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 获取出如流,并转换成String
	 * @return
	 */
	private static String inputString() {
		BufferedReader bufferedreader = new BufferedReader(
				new InputStreamReader(System.in));
		String s = null;
		try {
			s = bufferedreader.readLine();
		} catch (IOException ioexception) {
			ioexception.printStackTrace();
		}
		return s;
	}

	/**
	 * 
	 * @author Cheng 2008-9-27 上午10:32:18
	 * @version 1.0.0
	 */
	private static class ImageUtils {
		private Image	srcImage	= null;
		/**
		 * 源图片文件
		 */
		private File	srcFile		= null;
		/**
		 * 目标文件
		 */
		private File	destFile	= null;

		private String	fileSuffix	= null;

		/**
		 * 构造函数
		 * @param fileName
		 * @throws IOException
		 */
		public ImageUtils(String fileName) throws IOException {
			this(new File(fileName));
		}

		/**
		 * 
		 * @param fileName
		 * @throws IOException
		 */
		public ImageUtils(File fileName) throws IOException {
			File _file = fileName;
			_file.setReadOnly();
			this.srcFile = _file;
			this.fileSuffix = _file.getName().substring(
					(_file.getName().indexOf(".") + 1),
					(_file.getName().length()));
			this.destFile = new File(this.srcFile.getPath().substring(0,
					(this.srcFile.getPath().lastIndexOf(".")))
					+ PIC_TEMPORARY + "." + this.fileSuffix);
			srcImage = javax.imageio.ImageIO.read(_file);
		}

		/**
		 * 强制压缩/放大图片到固定的大小
		 * @param w int 新宽度
		 * @param h int 新高度
		 * @throws IOException
		 */
		public void resize(int w, int h) throws IOException {
			//构建图片对象
			BufferedImage _image = new BufferedImage(w, h,
					BufferedImage.TYPE_INT_RGB);
			//绘制缩小后的图
			_image.getGraphics().drawImage(srcImage, 0, 0, w, h, null);
			//输出到文件流
			FileOutputStream out = new FileOutputStream(destFile);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			encoder.encode(_image);
			out.flush();
			out.close();
			successed++;
		}
	}

	/**
	 * 测试Main
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.print("请输入目标文件夹:");
		String s = inputString();
		long currentTime = System.currentTimeMillis();
		ImageResizer resizer = new ImageResizer(s);
		resizer.operate(s);
		long finishTime = System.currentTimeMillis();
		long waste = finishTime - currentTime;
		resizer.write(s + "下共有" + allFiles + "个文件\n" + "\t成功:" + successed
				+ "\n\t失败:" + (allFiles - successed));
		resizer.write("耗时:" + waste / 1000 + "s");
		resizer.flush();
		System.out.println("处理完成,请看目标文件夹下日志文件。");
	}
}

 可能大家有更好的生成已有的缩略图的方法,欢迎介绍。

分享到:
评论
16 楼 allenxiaomai 2011-10-14  
你好啊~请教个问题:我现在要用Java做一个类似于资源管理器的东西,左边一栏我已经用JTree实现系统文件目录树,剩下右边一栏缩略图。请问高手是如何根据左边的文件夹里的文件在右边显示的文件缩略图。(且双击后有反应。)
15 楼 youzi560 2008-10-28  
刚写过一个递归复制文件.呵呵.递归生成缩略图那就下来学习一下.
14 楼 stephen830 2008-10-21  
有些格式的图片文件生成缩略图要特殊处理。比如:动画格式的gif测试过么?

有必要对支持的图片文件格式作一个说明。
13 楼 bluewave 2008-10-14  
我没做过图片方面的开发,感兴趣的就这几句代码。
_image.getGraphics().drawImage(srcImage, 0, 0, w, h, null);  
FileOutputStream out = new FileOutputStream(destFile);  
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);  
encoder.encode(_image);
递归遍历文件夹其实是很平常的事情。
不过楼主的代码写得很清晰,看起来很舒服。
12 楼 zjh0588 2008-10-12  
好似没什么特别
11 楼 21xionghua 2008-10-11  
比较好。建议:
让宽度锁定个具体值后,高度同比缩放。这样更利于在页面上显示。
10 楼 xellos 2008-10-09  
ak478288 写道
chhj_292 写道
各位有好的缩略图生成策略吼一生,这段代码不需要其他的辅助文件,直接可以运行。
下班走人咯。

JMagick调用IMageMagick,比较好的方式,目前很多图片处理的网站使用的方式


根我所知,许多网站是使用 ImagicMagick没错,但是不用JMagick。
因为
1 Jmagick是java的jni调用,很多网站不是java程序的。
2 就算是java的网站,鉴于JMagick和IM的版本问题,几乎可以与灵活而强大的linux的版本问题相提并论,所以也没几个人愿意去弄 JMagick吧?直接生成命令行调用 Imagick就行了。对于互联网来说,绑定了运行环境,依赖了服务器安装ImagickMagick,根本就不是问题。咱们不搞假想需求。
9 楼 lonelydark 2008-10-09  
lz,你测试一下~~用打印模式的图片~试一下~`看能识别吗~

感觉上不行~~`
8 楼 chhj_292 2008-10-09  
ak478288 写道
chhj_292 写道
各位有好的缩略图生成策略吼一生,这段代码不需要其他的辅助文件,直接可以运行。
下班走人咯。

JMagick调用IMageMagick,比较好的方式,目前很多图片处理的网站使用的方式


JMagick,太复杂,而且对于Linux和Windows又有不同的配置方法,而且这么简单的问题用它,岂不高射炮打蚊子-大材小用
7 楼 lonelydark 2008-10-09  
cmyk模式 的图片能处理吗?
6 楼 ak478288 2008-10-09  
chhj_292 写道
各位有好的缩略图生成策略吼一生,这段代码不需要其他的辅助文件,直接可以运行。
下班走人咯。

JMagick调用IMageMagick,比较好的方式,目前很多图片处理的网站使用的方式
5 楼 chhj_292 2008-10-09  
insiku 写道
这有难的地方?


这是一个仁者见仁,智者见智的问题。
4 楼 insiku 2008-10-08  
这有难的地方?
3 楼 chhj_292 2008-10-08  
aaron2007 写道
下载回家看看!递归还不是 很熟悉!

大家对读源码没兴趣,还是小生陋码不值一提?
都研究框架去了?

递归是指一种编程里经常要用的方法,重复不断的执行你想要的操作。
看看C语言的例子计较好理解^_^
2 楼 aaron2007 2008-10-08  
下载回家看看!递归还不是 很熟悉!
1 楼 chhj_292 2008-10-07  
各位有好的缩略图生成策略吼一生,这段代码不需要其他的辅助文件,直接可以运行。
下班走人咯。

相关推荐

    C#查看图片缩略图源码.rar

    此外,如果压缩包内的源码涉及到更复杂的功能,比如遍历文件夹获取所有图片的缩略图,那么可能使用了DirectoryInfo类来获取目录信息,以及FileInfo类来操作单个文件。同时,递归遍历子目录可能使用了递归函数。 ...

    nodejs实现获取本地文件夹下图片信息功能示例

    在处理图片文件时,我们通常需要知道图片的格式,以便进行进一步的操作,例如预览、缩略图生成等。 `readFileList`函数是实现递归遍历目录的核心部分。它接收两个参数:当前路径`path`和一个存储文件信息的数组`...

    BAT批处理脚本-全盘删除所有文件夹下的Thumbs.db.zip

    2. **路径遍历**:使用`for /R %i in (*) do`命令,可以递归地遍历当前目录及其子目录中的所有文件。`/R`参数表示递归,`%i`是代表当前文件的变量。 3. **条件判断**:在循环中,可以添加条件语句`if`来检查当前...

    TomThumb:批量生成视频文件的缩略图

    3. **处理子目录**:如果视频文件夹中包含子目录,使用`--recursive`参数可以递归处理所有子目录中的视频文件。 四、TomThumb的核心技术 TomThumb的工作原理主要是利用Python的`moviepy`库,这是一个强大的视频...

    KODExplorer 芒果云-资源管理器

    - 图片缩略图生成:小于5k则不生成(直接输出) - 加载文件列表改为异步方式,数据返回采用回调函数方式。增强体验 - 选中优化,文件&文件夹重命名、文件&文件夹新建 后自动选中。(f5增加回调。); - 选中保持,...

    MyAndroid图库

    Java的`java.io.File`类提供了方便的文件操作接口,如`listFiles()`用于获取指定目录下的所有文件和子目录。此外,`MIME`类型检测可以帮助确认文件类型,例如使用`java.nio.file.Files.probeContentType()`方法。 2...

    解决django FileFIELD的编码问题

    - `recursive`:可选参数,默认为False,如果设置为True,则FilePathField将递归搜索指定路径及其所有子目录。 - `allow_files`:可选参数,默认为True,表示是否允许存储文件。 - `allow_folders`:可选参数,默认...

    C#编程经验技巧宝典

    C#编程经验技巧宝典源代码,目录如下: 第1章 开发环境 1 &lt;br&gt;1.1 Visual Studio开发环境安装与配置 2 &lt;br&gt;0001 安装Visual Studio 2005开发环境须知 2 &lt;br&gt;0002 配置合适的Visual Studio 2005...

    Django中FilePathField字段的用法

    - 当设置为`True`时,`FilePathField`会递归地搜索指定路径下的所有子目录中的文件。 **4. `allow_files` 和 `allow_folders`** - 这两个参数都是可选的布尔值,默认分别为`True`和`False`。 - `allow_files`:指定...

Global site tag (gtag.js) - Google Analytics