|

楼主 |
发表于 2017-5-2 15:23:20
|
显示全部楼层
由于在微信里遇到了乱码之类的且压缩文件失效(见这个帖子http://bbs.wex5.com/forum.php?mod=viewthread&tid=120874&extra=),于是重新用java做了一个jar专门对上传的图片文件进行压缩。缩略图没有做了,有需要做的适当修改一下文件,同时输出一个小的图片,在前端里保存时就可以用增加的缩略图保存在mysql数据库应该就可以实现了。
大概意思就是:监控图片文件夹,有新增的就进行压缩后替换(需要缩略图的就多增加一句代码定义好宽高),用studio输出jar文件,用bat文件启动该jar并输出日志(正确和出错日志分开),最后用gpedit.msc添加开机脚本(bat文件)。
1、新建项目,包,类3个java文件:
2、ImgResize.java文件如下:
- package 包名;
- import java.io.*;
- //import java.util.Date;
- import java.awt.*;
- import java.awt.image.*;
- import javax.imageio.ImageIO;
- import com.sun.image.codec.jpeg.*;
- /**
- * 图片压缩处理
- */
- public class ImgResize {
- private Image img;
- private int width;
- private int height;
- private String pathtoresize;
-
- /**
- * 构造函数
- */
- // public ImgResize() throws IOException {
- public ImgResize(String fileName) throws IOException {
- File file = new File(fileName);// 读入文件
- pathtoresize = fileName;
- img = ImageIO.read(file); // 构造Image对象
- width = img.getWidth(null); // 得到源图宽
- height = img.getHeight(null); // 得到源图长
- }
- /**
- * 按照宽度还是高度进行压缩
- * @param w int 最大宽度
- * @param h int 最大高度
- */
- public void resizeFix(int w, int h) throws IOException {
- if (width / height > w / h) {
- resizeByWidth(w);
- } else {
- resizeByHeight(h);
- }
- }
- /**
- * 以宽度为基准,等比例放缩图片
- * @param w int 新宽度
- */
- public void resizeByWidth(int w) throws IOException {
- int h = (int) (height * w / width);
- resize(w, h);
- }
- /**
- * 以高度为基准,等比例缩放图片
- * @param h int 新高度
- */
- public void resizeByHeight(int h) throws IOException {
- int w = (int) (width * h / height);
- resize(w, h);
- }
- /**
- * 强制压缩/放大图片到固定的大小
- * @param w int 新宽度
- * @param h int 新高度
- */
- public void resize(int w, int h) throws IOException {
- // SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢
- BufferedImage image = new BufferedImage(w, h,BufferedImage.TYPE_INT_RGB );
- image.getGraphics().drawImage(img, 0, 0, w, h, null); // 绘制缩小后的图
- File destFile = new File(pathtoresize);
- FileOutputStream out = new FileOutputStream(destFile); // 输出到文件流
- // 可以正常实现bmp、png、gif转jpg
- JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
- encoder.encode(image); // JPEG编码
- out.close();
- }
- }
复制代码 3、FileListenerChange.java文件内容:
- package 包名;
- import java.io.File;
- import org.apache.commons.io.monitor.FileAlterationMonitor;
- import org.apache.commons.io.monitor.FileAlterationObserver;
-
- public class FileListenerChange {
-
- public static void main(String[] args) {
- try {
- // 构造观察类主要提供要观察的文件或目录,当然还有详细信息的filter
- FileAlterationObserver observer = new FileAlterationObserver(
- new File("你的图片文件夹路径"), null);
- // 构造收听类
- FileListenerAdaptor listener = new FileListenerAdaptor();
- // 为观察对象添加收听对象
- observer.addListener(listener);
- // 配置Monitor,第一个参数单位是毫秒,是监听的间隔;第二个参数就是绑定我们之前的观察对象。
- FileAlterationMonitor fileMonitor = new FileAlterationMonitor(
- 5000, new FileAlterationObserver[] { observer });
- // 启动开始监听
- fileMonitor.start();
- } catch (Exception e) {
- System.out.println("监听启动失败!");
- e.printStackTrace();
- }
- }
- }
复制代码
4、监听文件变化,在新建文件时(onFileCreate)写代码,FileListenerAdaptor.java:
- package 包名;
- import java.io.File;
- import java.io.IOException;
- import java.util.Date;
- import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
- import org.apache.commons.io.monitor.FileAlterationObserver;
-
- public class FileListenerAdaptor extends FileAlterationListenerAdaptor {
- @Override
- public void onStart(FileAlterationObserver arg0) {
- System.out.println(new Date()+",begin listening!");
- super.onStart(arg0);
- }
-
- @Override
- public void onStop(FileAlterationObserver arg0) {
- System.out.println(new Date()+",end listening!");
- super.onStop(arg0);
- }
-
- @Override
- public void onDirectoryCreate(File fold) {
- System.out.println(new Date()+",fold: " + fold.getAbsolutePath() + " is created.");
- super.onDirectoryCreate(fold);
- }
-
- @Override
- public void onDirectoryChange(File fold) {
- System.out.println(new Date()+",fold: " + fold.getAbsolutePath() + " is changed.");
- super.onDirectoryChange(fold);
- }
-
- @Override
- public void onDirectoryDelete(File fold) {
- System.out.println(new Date()+",fold: " + fold.getAbsolutePath() + " is deleted.");
- super.onDirectoryDelete(fold);
- }
-
- @Override
- public void onFileCreate(File file) {
- System.out.println(new Date()+",file: " + file.getAbsolutePath() + " is created.");
- String pathtoresize = file.getAbsolutePath();
- long size = file.length();
- // System.out.println("新创建文件大小: " + size);
- if(size > 262144){
- System.out.println("新创建文件大小: " + size + ",大于256Kb的图片将被压缩....");
- try {
- ImgResize imgCom = new ImgResize(pathtoresize);
- imgCom.resizeFix(800, 800); //图片的最大尺寸
- } catch (IOException e) {
- // TODO 自动生成的 catch 块
- e.printStackTrace();
- }
- } else{
- System.out.println("新创建文件大小: " + size + ",小于256Kb,取消压缩....");
- }
- super.onFileCreate(file);
- }
-
- @Override
- public void onFileChange(File file) {
- System.out.println(new Date()+",file: " + file.getAbsolutePath() + " is changed.");
- super.onFileChange(file);
- }
-
- @Override
- public void onFileDelete(File file) {
- System.out.println(new Date()+",file: " + file.getAbsolutePath() + " is deleted");
- super.onFileDelete(file);
- }
-
- }
复制代码
5、输出为jar文件:
6、创建bat文件,我的bat和jar在一个文件夹下面,日志路径大家自定吧,正确日志每次启动一个文件,错误日志就进行追加,我的为:c:\resize_log,内容如下:
- @echo off
- if not defined s set s= && start /min "" %0& exit
- set today=%date:~0,4%-%date:~5,2%-%date:~8,2%
- java -jar xxxxxxxx.jar >c:\resize_log\log%today%_%time:~0,2%%time:~3,2%%time:~6,2%.txt 2>>c:\resize_log\errolog%today%.txt
- pause
复制代码
7、添加启动脚本:
8、像这个样子:
备注:
由于我本身也是菜鸟,大家也可以晚上查查。这个jar生成后进行监听处理新加入的图片文件,即使attachmentsimple上传的不带扩展名的都可以。
我大概看了一个,不停的张贴图片文件,每次100个,共10次,内存从16.7M一直到500M,之后回落至100M左右,cpu(4核)会有1秒左右到100%,基本都是在30%附件。我还在一台768的虚拟机里测试,内存在15M至60M之间直到处理完照片(200张左右,没有用1000张测试)。
一个重要的问题:在本地测试没有问题,在虚拟机里测试页没有问题,到了服务器会报错:
- Exception in thread "Thread-0" java.lang.NullPointerException
- at mfxxl.ImgResize.<init>(ImgResize.java:29)
- at mfxxl.FileListenerAdaptor.onFileCreate(FileListenerAdaptor.java:51)
- at org.apache.commons.io.monitor.FileAlterationObserver.doCreate(FileAlterationObserver.java:379)
- at org.apache.commons.io.monitor.FileAlterationObserver.checkAndNotify(FileAlterationObserver.java:345)
- at org.apache.commons.io.monitor.FileAlterationObserver.checkAndNotify(FileAlterationObserver.java:335)
- at org.apache.commons.io.monitor.FileAlterationObserver.checkAndNotify(FileAlterationObserver.java:335)
- at org.apache.commons.io.monitor.FileAlterationObserver.checkAndNotify(FileAlterationObserver.java:335)
- at org.apache.commons.io.monitor.FileAlterationObserver.checkAndNotify(FileAlterationObserver.java:335)
- at org.apache.commons.io.monitor.FileAlterationObserver.checkAndNotify(FileAlterationObserver.java:304)
- at org.apache.commons.io.monitor.FileAlterationMonitor.run(FileAlterationMonitor.java:182)
- at java.lang.Thread.run(Unknown Source)
复制代码 估计会不会是使用NFS系统引起的不知道,其余的系统都是正常运行,即使低内存也没有出错的情况!
如果后端java基础好还是直接写为好,毕竟自己不行就做了这么一个。结贴!
|
|