Runtime.exec()调用imageMagick实现图片缩放

本文介绍了解决Java中Runtime.getRuntime().exec()方法导致程序阻塞的问题。通过创建独立线程处理stdout和stderr流,确保了程序流畅运行,并提供了一个图片缩放工具类的具体实现案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

牛牛发现问题的原因,Process  process=Runtime.getRuntime().exec("");中产生停滞(阻塞,blocking)。

这个是因为Runtime.getRuntime().exec()要自己去处理stdout和stderr的。 
所以如果你想让程序正常运行的话,请务必将上述用别的线程流取走。 

  1. public class PictureZoomUtils {   
  2.     private static Log logger = LogFactory.getLog(PictureZoomUtils.class);   
  3.        
  4.     /**  
  5.      * image magick convert.exe的绝对路径  
  6.      */  
  7.     private String convertExe;   
  8.   
  9.     public void zoom(File input, File output, int width, int height) throws Exception {   
  10.         StringBuilder command = new StringBuilder();   
  11.         command.append(convertExe).append(" ").append(input.getAbsolutePath()).append(" -resize ").append(width)   
  12.                 .append("x").append(height)// 改变尺寸 -resize 120x120   
  13.                 .append(" -colors").append(" 100"// 颜色数:设定图片采用的颜色数,如果是生成png或gif图片应指定这个参数   
  14.                 .append(" +profile \"*\" "// 图片中不存储附加信息,必须使用,否则生成图片过大   
  15.                 .append(output.getAbsolutePath());   
  16.   
  17.         try{   
  18.             Process process = Runtime.getRuntime().exec(command.toString());   
  19.   
  20.             // any error message?   
  21.             StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), "ERROR");   
  22.             // any output?   
  23.             StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream(), "OUTPUT");   
  24.   
  25.             errorGobbler.start();   
  26.             outputGobbler.start();   
  27.   
  28.             process.waitFor(); // 永远要先从标准错误流中读取,然后再读取标准输出流, 最后在执行waitFor   
  29.         }catch(Throwable t){   
  30.             logger.error(t);   
  31.         }   
  32.            
  33.     }   
  34.   
  35.     public void setConvertExe(String convertExe) {   
  36.         this.convertExe = convertExe;   
  37.     }   
  38.   
  39.     public String getConvertExe() {   
  40.         return convertExe;   
  41.     }   
  42.   
  43. }   
  44.   
  45. class StreamGobbler extends Thread {   
  46.     private static Log logger = LogFactory.getLog(StreamGobbler.class);   
  47.        
  48.     private InputStream is;   
  49.     private String type; // 输出流的类型ERROR或OUTPUT   
  50.   
  51.     public StreamGobbler(InputStream is, String type) {   
  52.         this.is = is;   
  53.         this.type = type;   
  54.     }   
  55.   
  56.     public void run() {   
  57.         try {   
  58.             InputStreamReader isr = new InputStreamReader(is);   
  59.             BufferedReader br = new BufferedReader(isr);   
  60.             String line = null;   
  61.             while ((line = br.readLine()) != null) {   
  62.                 System.out.println(type + ">" + line);   
  63.                 System.out.flush();   
  64.             }   
  65.         } catch (IOException ioe) {   
  66.             logger.error(ioe);   
  67.         }   
  68.     }   
  69. }  
public class PictureZoomUtils {   private static Log logger = LogFactory.getLog(PictureZoomUtils.class);      /**    * image magick convert.exe的绝对路径    */   private String convertExe;     public void zoom(File input, File output, int width, int height) throws Exception {    StringBuilder command = new StringBuilder();    command.append(convertExe).append(" ").append(input.getAbsolutePath()).append(" -resize ").append(width)      .append("x").append(height)// 改变尺寸 -resize 120x120      .append(" -colors").append(" 100") // 颜色数:设定图片采用的颜色数,如果是生成png或gif图片应指定这个参数      .append(" +profile \"*\" ") // 图片中不存储附加信息,必须使用,否则生成图片过大      .append(output.getAbsolutePath());      try{     Process process = Runtime.getRuntime().exec(command.toString());       // any error message?     StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), "ERROR");     // any output?     StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream(), "OUTPUT");       errorGobbler.start();     outputGobbler.start();       process.waitFor(); // 永远要先从标准错误流中读取,然后再读取标准输出流, 最后在执行waitFor    }catch(Throwable t){     logger.error(t);    }       }     public void setConvertExe(String convertExe) {    this.convertExe = convertExe;   }     public String getConvertExe() {    return convertExe;   }    }    class StreamGobbler extends Thread {   private static Log logger = LogFactory.getLog(StreamGobbler.class);      private InputStream is;   private String type; // 输出流的类型ERROR或OUTPUT     public StreamGobbler(InputStream is, String type) {    this.is = is;    this.type = type;   }     public void run() {    try {     InputStreamReader isr = new InputStreamReader(is);     BufferedReader br = new BufferedReader(isr);     String line = null;     while ((line = br.readLine()) != null) {      System.out.println(type + ">" + line);      System.out.flush();     }    } catch (IOException ioe) {     logger.error(ioe);    }   }  }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值