java 图片缩略图的两种方法

来源:互联网 发布:手机知乎提问没人回答 编辑:程序博客网 时间:2024/05/22 09:01

最近网上看到两种不同的Java图片缩略图的绘制方案

 

    第一种,使用Graphics().drawImage按照一定的比例重新绘制图像。

 

Java代码  收藏代码
  1. package com.image.suoluetu;  
  2.   
  3. import java.io.*;  
  4. import java.awt.*;  
  5. import java.awt.image.*;  
  6. import com.sun.image.codec.jpeg.*;  
  7.   
  8. public class DrawImage {  
  9.     private String destFile;  
  10.     private int width;  
  11.     private int height;  
  12.     private Image img;  
  13.   
  14.     public DrawImage(String fileName) throws IOException {  
  15.         File _file = new File(fileName); // 读入文件  
  16.         _file.getName();  
  17.         this.destFile = "D:/dage2.jpg";// this.srcFile.substring(0,  
  18.                                         // this.srcFile.lastIndexOf("."))  
  19.                                         // +"_s.jpg";  
  20.         img = javax.imageio.ImageIO.read(_file); // 构造Image对象  
  21.         width = img.getWidth(null); // 得到源图宽  
  22.         height = img.getHeight(null); // 得到源图长  
  23.     }  
  24.   
  25.     /** 
  26.      * /** 
  27.      *  
  28.      * @param args 
  29.      */  
  30.     public void resize(int w, int h) throws IOException {  
  31.         try {  
  32.             BufferedImage _image = new BufferedImage(w, h,  
  33.                     BufferedImage.TYPE_INT_RGB);  
  34.             _image.getGraphics().drawImage(img, 00, w, h, null); // 绘制缩小后的图  
  35.             FileOutputStream newimageout = new FileOutputStream(destFile); // 输出到文件流  
  36.             /* 
  37.              * JPEGImageEncoder 将图像缓冲数据编码为 JPEG 数据流。该接口的用户应在 Raster 或 
  38.              * BufferedImage 中提供图像数据,在 JPEGEncodeParams 对象中设置必要的参数, 并成功地打开 
  39.              * OutputStream(编码 JPEG 流的目的流)。JPEGImageEncoder 接口可 将图像数据编码为互换的缩略 
  40.              * JPEG 数据流,该数据流将写入提供给编码器的 OutputStream 中。 
  41.              * 注意:com.sun.image.codec.jpeg 包中的类并不属于核心 Java API。它们属于 Sun 发布的 JDK 
  42.              * 和 JRE 产品的组成部分。虽然其它获得许可方可能选择发布这些类,但开发人员不能寄 希望于从非 Sun 
  43.              * 实现的软件中得到它们。我们期望相同的功能最终可以在核心 API 或标准扩 展中得到。 
  44.              */  
  45.             JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(newimageout);  
  46.             encoder.encode(_image); // 近JPEG编码  
  47.             newimageout.close();  
  48.         } catch (Exception ex) {  
  49.             ex.printStackTrace();  
  50.         }  
  51.     }  
  52.   
  53.     /** 
  54.      * 按照固定的比例缩放图片 
  55.      *  
  56.      * @param t 
  57.      *            double 比例 
  58.      * @throws IOException 
  59.      */  
  60.     public void resize(double t) throws IOException {  
  61.         int w = (int) (width * t);  
  62.         int h = (int) (height * t);  
  63.         resize(w, h);  
  64.     }  
  65.   
  66.     /** 
  67.      * 以宽度为基准,等比例放缩图片 
  68.      *  
  69.      * @param w 
  70.      *            int 新宽度 
  71.      * @throws IOException 
  72.      */  
  73.     public void resizeByWidth(int w) throws IOException {  
  74.         int h = (int) (height * w / width);  
  75.         resize(w, h);  
  76.     }  
  77.   
  78.     /** 
  79.      * 以高度为基准,等比例缩放图片 
  80.      *  
  81.      * @param h 
  82.      *            int 新高度 
  83.      * @throws IOException 
  84.      */  
  85.     public void resizeByHeight(int h) throws IOException {  
  86.         int w = (int) (width * h / height);  
  87.         resize(w, h);  
  88.     }  
  89.   
  90.     /** 
  91.      * 按照最大高度限制,生成最大的等比例缩略图 
  92.      *  
  93.      * @param w 
  94.      *            int 最大宽度 
  95.      * @param h 
  96.      *            int 最大高度 
  97.      * @throws IOException 
  98.      */  
  99.     public void resizeFix(int w, int h) throws IOException {  
  100.         if (width / height > w / h) {  
  101.             resizeByWidth(w);  
  102.         } else {  
  103.             resizeByHeight(h);  
  104.         }  
  105.     }  
  106.   
  107.     /** 
  108.      * 设置目标文件名 setDestFile 
  109.      *  
  110.      * @param fileName 
  111.      *            String 文件名字符串 
  112.      */  
  113.     public void setDestFile(String fileName) throws Exception {  
  114.         if (!fileName.endsWith(".jpg")) {  
  115.             throw new Exception("Dest File Must end with \".jpg\".");  
  116.         }  
  117.         destFile = fileName;  
  118.     }  
  119.   
  120.     /** 
  121.      * 获取目标文件名 getDestFile 
  122.      */  
  123.     public String getDestFile() {  
  124.         return destFile;  
  125.     }  
  126.   
  127.     /** 
  128.      * 获取图片原始宽度 getSrcWidth 
  129.      */  
  130.     public int getSrcWidth() {  
  131.         return width;  
  132.     }  
  133.   
  134.     /** 
  135.      * 获取图片原始高度 getSrcHeight 
  136.      */  
  137.     public int getSrcHeight() {  
  138.         return height;  
  139.     }  
  140.   
  141.     public static void main(String[] args) {  
  142.         // TODO Auto-generated method stub  
  143.         try {  
  144.             DrawImage ccc = new DrawImage("D:/dage.jpg");  
  145.             ccc.resizeFix(600400);  
  146.         } catch (IOException e) {  
  147.             // TODO Auto-generated catch block  
  148.             e.printStackTrace();  
  149.         }  
  150.     }  
  151. }  

 第二种:使用仿射转换的技术进行图片绘制。

 

Java代码  收藏代码
  1. package com.image.suoluetu;  
  2. import javax.imageio.ImageIO;  
  3. import java.awt.image.BufferedImage;  
  4. import java.io.File;  
  5. import java.awt.image.AffineTransformOp;  
  6. import java.awt.geom.AffineTransform;  
  7.   
  8. public class AffineTransImage {  
  9.   
  10.     public static void main (String argv[]) {  
  11.         try {  
  12.             File fi = new File("D:/dage.jpg"); //大图文件  
  13.             File fo = new File("D:/dagex.jpg"); //将要转换出的小图文件  
  14.             int nw = 500;  
  15.             /* 
  16.             AffineTransform 类表示 2D 仿射变换,它执行从 2D 坐标到其他 2D 
  17.             坐标的线性映射,保留了线的“直线性”和“平行性”。可以使用一系 
  18.             列平移、缩放、翻转、旋转和剪切来构造仿射变换。 
  19.             */  
  20.             AffineTransform transform = new AffineTransform();  
  21.             BufferedImage bis = ImageIO.read(fi); //读取图片  
  22.             int w = bis.getWidth();  
  23.             int h = bis.getHeight();  
  24.              //double scale = (double)w/h;  
  25.             int nh = (nw*h)/w ;  
  26.             double sx = (double)nw/w;  
  27.             double sy = (double)nh/h;  
  28.             transform.setToScale(sx,sy); //setToScale(double sx, double sy) 将此变换设置为缩放变换。  
  29.             System.out.println(w + " " +h);  
  30.             /* 
  31.              * AffineTransformOp类使用仿射转换来执行从源图像或 Raster 中 2D 坐标到目标图像或 
  32.              *  Raster 中 2D 坐标的线性映射。所使用的插值类型由构造方法通过 
  33.              *  一个 RenderingHints 对象或通过此类中定义的整数插值类型之一来指定。 
  34.             如果在构造方法中指定了 RenderingHints 对象,则使用插值提示和呈现 
  35.             的质量提示为此操作设置插值类型。要求进行颜色转换时,可以使用颜色 
  36.             呈现提示和抖动提示。 注意,务必要满足以下约束:源图像与目标图像 
  37.             必须不同。 对于 Raster 对象,源图像中的 band 数必须等于目标图像中 
  38.             的 band 数。 
  39.             */  
  40.             AffineTransformOp ato = new AffineTransformOp(transform,null);  
  41.             BufferedImage bid = new BufferedImage(nw,nh,BufferedImage.TYPE_3BYTE_BGR);  
  42.             /* 
  43.              * TYPE_3BYTE_BGR 表示一个具有 8 位 RGB 颜色分量的图像, 
  44.              * 对应于 Windows 风格的 BGR 颜色模型,具有用 3 字节存 
  45.              * 储的 Blue、Green 和 Red 三种颜色。 
  46.             */  
  47.             ato.filter(bis,bid);  
  48.             ImageIO.write(bid,"jpeg",fo);  
  49.         } catch(Exception e) {  
  50.             e.printStackTrace();  
  51.         }  
  52.     }  
  53.   
  54. }  
1 0
原创粉丝点击