Java图片处理 - 创建工具类

Java图片处理 - 创建工具类


Java原生代码实现工具类

Java原生代码实现使用jdk内部的GIFImageReader、GIFImageWriter等类,maven在编译的时候会提示这是sun公司的私有API,在1.7、1.8版的JDK中已经删除,所以是有风险的。

import com.oupeng.joke.domain.Image;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.imageio.plugins.gif.GIFImageReader;
import com.sun.imageio.plugins.gif.GIFImageReaderSpi;
import com.sun.imageio.plugins.gif.GIFImageWriter;
import com.sun.imageio.plugins.gif.GIFImageWriterSpi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.spi.ImageWriterSpi;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.FileImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;

public class ImageUtils {
    private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);


//  public static void main(String[] args) {
//        ImageUtils.getGifOneFrame("/nh/logs/c.gif", 5);
//  }

    /**
     * 获取GIF图片一帧图片
     * @param src       GIF图地址
     * @param target    目标地址
     * @param frame     第几帧
     * @return
     */
    public static boolean getGifOneFrame(String src, String target, int frame) {
        FileImageInputStream in = null;
        FileImageOutputStream out = null;
        try {
            in = new FileImageInputStream(new File(src));
            ImageReaderSpi readerSpi = new GIFImageReaderSpi();
            GIFImageReader gifReader = (GIFImageReader) readerSpi.createReaderInstance();
            gifReader.setInput(in);
            int num = gifReader.getNumImages(true);
            if (num > frame) {
                ImageWriterSpi writerSpi = new GIFImageWriterSpi();
                GIFImageWriter writer = (GIFImageWriter) writerSpi.createWriterInstance();
                for (int i = 0; i < num; i++) {
                    if (i == frame) {
                        File newfile = new File(target);
                        out = new FileImageOutputStream(newfile);
                        writer.setOutput(out);
                        writer.write(gifReader.read(i));
                        return true;
                    }
                }
            }
            return false;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        } finally {
            close(in, out);
        }
    }

    /**
     * 复制文件
     * @param src
     * @param target
     * @return
     */
    public static boolean copyImageToPath(String src, String target) {
        InputStream in = null;
        OutputStream out = null;
        try {
            File srcFile = new File(src);
            File targetFile = new File(target);
            in = new FileInputStream(srcFile);
            out = new FileOutputStream(targetFile);
            byte[] bytes = new byte[1024];
            int len = -1;
            while ((len = in.read(bytes)) != -1) {
                out.write(bytes, 0, len);
            }
            return true;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        } finally {
            close(in, out);
        }
    }

    /**
     * 获取图片宽高
     * @param file
     * @return
     */
    public static void getImgWidthAndHeight(File file, Image image) {
        InputStream is = null;
        BufferedImage src ;
        try {
            if(image == null){
                image = new Image();
            }
            is = new FileInputStream(file);
            src = javax.imageio.ImageIO.read(is);
            image.setWidth(src.getWidth());
            image.setHeight(src.getHeight());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            close(is, null);
        }
    }

    /**
     * 获取图片宽高
     * @param file
     * @return
     */
    public static Image getImgWidthAndHeight(File file) {
        InputStream is = null;
        BufferedImage src ;
        Image image = new Image();
        try {
            is = new FileInputStream(file);
            src = javax.imageio.ImageIO.read(is);
            image.setWidth(src.getWidth());
            image.setHeight(src.getHeight());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            close(is, null);
        }
        return image;
    }

    /**
     * 获取图片宽度
     * @param file
     * @return
     */
    public static int getImgWidth(File file) {
        InputStream is = null;
        BufferedImage src = null;
        int ret = 0;
        try {
            is = new FileInputStream(file);
            src = javax.imageio.ImageIO.read(is);
            ret = src.getWidth(); // 得到源图宽
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            close(is, null);
        }
        return ret;
    }


    /**
     * 获取图片高度
     * @param file  图片文件
     * @return 高度
     */
    public static int getImgHeight(File file) {
        InputStream is = null;
        BufferedImage src;
        int ret = 0;
        try {
            is = new FileInputStream(file);
            src = javax.imageio.ImageIO.read(is);
            ret = src.getHeight(); // 得到源图高
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            close(is, null);
        }
        return ret;
    }

    /**
     * 格式转换
     * @param src
     * @param target
     * @param format
     * @return
     */
    public static Image generateImage(String src, String target, String format, Image image) {
        try {
            if(image == null){
                image = new Image();
            }
            File input = new File(src);
            BufferedImage bim = ImageIO.read(input);
            image.setWidth(bim.getWidth());
            image.setHeight(bim.getHeight());
            File output = new File(target);
            ImageIO.write(bim, format, output);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return image;
    }


    /**
     * 关闭资源
     * @param in
     * @param out
     */
    private static void close(Closeable in, Closeable out) {
        try {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        } catch (Exception e1) {
            log.error(e1.getMessage(), e1);
        }
    }
}
    /**
     * 缩放图片
     * @param src
     * @return
     */
    public static BufferedImage zoomImage(String src, int targetWidth) {
        BufferedImage result = null;
        try {
            File srcfile = new File(src);
            if (!srcfile.exists()) {
                log.error("源文件不存在:{}", src);
                return null;
            }
            BufferedImage im = ImageIO.read(srcfile);
            /* 原始图像的宽度和高度 */
            int width = im.getWidth();
            int height = im.getHeight();
            //压缩计算
            float resizeTimes = (float)targetWidth / (float)width;
            BigDecimal bd  =   new  BigDecimal((double)resizeTimes);
            bd   =  bd.setScale(1 ,4); // (1:小数点位数, 2:表示四舍五入,可以选择其他舍值方式,例如去尾,等等.
            resizeTimes   =  bd.floatValue();
//            float resizeTimes = 0.3f;  /*这个参数是要转化成的倍数,如果是1就是转化成1倍*/
            /* 调整后的图片的宽度和高度 */
            int toWidth = (int) (width * resizeTimes);
            int toHeight = (int) (height * resizeTimes);

            /* 新生成结果图片 */
            result = new BufferedImage(toWidth, toHeight, BufferedImage.TYPE_INT_RGB);
            result.getGraphics().drawImage( im.getScaledInstance(toWidth, toHeight, java.awt.Image.SCALE_SMOOTH), 0, 0, null);
        } catch (Exception e) {
            System.out.println("创建缩略图发生异常" + e.getMessage());
        }
        return result;
    }

    public static boolean writeHighQuality(BufferedImage im, String fileFullPath) {
        try {
                /*输出到文件流*/
            FileOutputStream newimage = new FileOutputStream(fileFullPath);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(newimage);
            JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(im);
                /* 压缩质量 */
            jep.setQuality(0.9f, true);
            encoder.encode(im, jep);
               /*近JPEG编码*/
            newimage.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean widthCutting(String source, String target, int width){
        return ImageUtil.writeHighQuality(ImageUtil.zoomImage(source, width), target);
    }

上面的工具类中使用了Image对象

public class Image {
    /**
     * 宽度
     */
    private Integer width;
    /**
     * 高度
     */
    private Integer height;
    /**
     * 路径
     */
    private String path;


    public Integer getWidth() {
        return width;
    }

    public void setWidth(Integer width) {
        this.width = width;
    }

    public Integer getHeight() {
        return height;
    }

    public void setHeight(Integer height) {
        this.height = height;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }
}

使用第三方im4java库创建工具类

第一步,需要在项目中加入im4java的Maven依赖

        <dependency>
            <groupId>org.im4javagroupId>
            <artifactId>im4javaartifactId>
            <version>1.4.0version>
        dependency>

第二步, 创建工具类

import org.im4java.core.ConvertCmd;
import org.im4java.core.IMOperation;
import org.im4java.core.IdentifyCmd;
import org.im4java.core.ImageCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class Im4JavaUtils {
    private static final Logger logger = LoggerFactory.getLogger(Im4JavaUtils.class);

    /** 是否使用 GraphicsMagick (Windows下为true) **/
    private static final boolean USE_GRAPHICS_MAGICK_PATH = false;
    /** ImageMagick 安装目录 **/
    private static final String IMAGE_MAGICK_PATH = "C:\\Program Files\\ImageMagick-6.3.9-Q8";
    /** GraphicsMagick 安装目录 **/
    private static final String GRAPHICS_MAGICK_PATH = "C:\\Program Files\\GraphicsMagick-1.3.23-Q8";

    /**
     * 获取 ImageCommand
     * @param comm 命令类型(convert, identify)
     * @return
     */
    private static ImageCommand getImageCommand(String comm) {
        ImageCommand cmd = null;
        if ("convert".equalsIgnoreCase(comm)) {
            cmd = new ConvertCmd(USE_GRAPHICS_MAGICK_PATH);
        } else if ("identify".equalsIgnoreCase(comm)) {
            cmd = new IdentifyCmd(USE_GRAPHICS_MAGICK_PATH);
        } // else if....
//        Windows环境下需要配置应用路径
        if (cmd != null && System.getProperty("os.name").toLowerCase().indexOf("windows") != -1) {
            cmd.setSearchPath(USE_GRAPHICS_MAGICK_PATH ? GRAPHICS_MAGICK_PATH : IMAGE_MAGICK_PATH);
        }
        return cmd;
    }


    /**
     * 降低品质,以减小文件大小
     * @param path 原文件路径
     * @param des 目标文件路径
     * @param quality 保留品质(1-100)
     * @throws Exception
     */
    public static void reduceQuality(String path, String des, double quality) throws Exception {
        createDirectory(des);
        IMOperation op = new IMOperation();
        op.addImage(path);
        op.quality(quality);
        op.addImage(des);
        ConvertCmd cmd = (ConvertCmd) getImageCommand("convert");
        cmd.run(op);
    }

    /**
     * 改变图片大小比例
     * @param path 原文件路径
     * @param des 目标文件路径
     * @param ratio 缩放比例
     * @throws Exception
     */
    public static void resizeImage(String path, String des, String ratio) throws Exception {
//        创建目标文件
        createDirectory(des);
        IMOperation op = new IMOperation();
        op.addImage(path);
        op.addRawArgs(ratio);
        op.addImage(des);

        ConvertCmd cmd = (ConvertCmd) getImageCommand("convert");
        cmd.run(op);
    }

    /**
     * 等比缩放图片(如果width为空,则按height缩放; 如果height为空,则按width缩放)
     * @param path 原文件路径
     * @param des 目标文件路径
     * @param width 缩放后的宽度
     * @param height 缩放后的高度
     * @param sample 是否以缩放方式,而非缩略图方式
     * @throws Exception 
     */
    public static void scaleResizeImage(String path, String des, Integer width, Integer height, boolean sample) throws Exception {
        createDirectory(des);
        IMOperation op = new IMOperation();
        op.addImage(path);
        if (sample) op.resize(width, height);
        else op.sample(width, height);
        op.addImage(des);
        ConvertCmd cmd = (ConvertCmd) getImageCommand("convert");
        cmd.run(op);
    }

    /**
     * 从原图中裁剪出新图
     * @param path 原文件路径
     * @param des 目标文件路径
     * @param x 原图左上角
     * @param y 原图左上角
     * @param width 新图片宽度
     * @param height 新图片高度
     * @throws Exception
     */
    public static void cropImage(String path, String des, int x, int y, int width, int height) throws Exception {
        createDirectory(des);
        IMOperation op = new IMOperation();
        op.addImage(path);
        op.crop(width, height, x, y);
        op.addImage(des);
        ConvertCmd cmd = (ConvertCmd) getImageCommand("convert");
        cmd.run(op);
    }

    /**
     * 将图片分割为若干小图
     * @param path 原文件路径
     * @param des 目标文件路径
     * @param width 指定宽度(默认为完整宽度)
     * @param height 指定高度(默认为完整高度)
     * @return 小图路径
     * @throws Exception
     */
    public static List subsectionImage(String path, String des, Integer width, Integer height) throws Exception {
        createDirectory(des);
        IMOperation op = new IMOperation();
        op.addImage(path);
        op.crop(width, height);
        op.addImage(des);

        ConvertCmd cmd = (ConvertCmd) getImageCommand("convert");
        cmd.run(op);

        return getSubImages(des);
    }

    /**
     * 
     * 
  • 去除Exif信息
  • *
  • 按指定的宽度等比缩放图片
  • *
  • 降低图片品质
  • *
  • 将图片分割分指定高度的小图
  • * * @param path 原文件路径 * @param des 目标文件路径 * @param width 指定宽度 * @param subImageHeight 指定高度 * @param quality 保留品质 * @return 小图路径 * @throws Exception *
    */
    public static List resizeAndCropImage(String path, String des, int width, int subImageHeight, double quality) throws Exception { createDirectory(des); IMOperation op = new IMOperation(); op.addImage(path); // op.profile("*"); op.resize(width, null); op.quality(quality); op.crop(null, subImageHeight); op.addImage(des); ConvertCmd cmd = (ConvertCmd) getImageCommand("convert"); cmd.run(op); return getSubImages(des); } /*** * 切图 * @param source path 源图片路径 * @param target 目标图片路径 * @param width 限宽 * @param subImageHeight 最终高度 * @param quality 图片质量(0~100) * @throws Exception */ public static void cropImage(String source, String target, int width, int subImageHeight, double quality) throws Exception { createDirectory(target); IMOperation op = new IMOperation(); op.addImage(source); op.resize(width, null); op.quality(quality); op.crop(null, subImageHeight, 0, 15); op.addImage(target); ConvertCmd cmd = (ConvertCmd) getImageCommand("convert"); cmd.run(op); } /** * 拷贝图片 - 同步 * @param source * @param target * @return * @throws Exception */ public static boolean copyImage(String source, String target) throws Exception { createDirectory(target); IMOperation op = new IMOperation(); op.addImage(source); op.addImage(target); ConvertCmd cmd = (ConvertCmd) getImageCommand("convert"); cmd.setAsyncMode(false); cmd.run(op); return true; } /** * 拷贝图片 - 异步 * @param source * @param target * @return * @throws Exception */ public static void copyImageAsync(String source, String target) throws Exception { createDirectory(target); IMOperation op = new IMOperation(); op.addImage(source); op.addImage(target); ConvertCmd cmd = (ConvertCmd) getImageCommand("convert"); cmd.setAsyncMode(true); cmd.run(op); } /** * 创建目录 * @param path */ private static void createDirectory(String path) { File file = new File(path); if (file.exists()){ return; } file.getParentFile().mkdirs(); } /** * 获取图片分割后的小图路径 * @param des 目录路径 * @return 小图路径 */ private static List getSubImages(String des) { String fileDir = des.substring(0, des.lastIndexOf(File.separatorChar)); // 文件所在目录 String fileName = des.substring(des.lastIndexOf(File.separatorChar) + 1); // 文件名称 String n1 = fileName.substring(0, fileName.lastIndexOf(".")); // 文件名(无后缀) String n2 = fileName.replace(n1, ""); // 后缀 List fileList = new ArrayList(); String path = null; for (int i = 0;; i++) { path = fileDir + File.separatorChar + n1 + "-" + i + n2; if (new File(path).exists()) fileList.add(path); else break; } return fileList; } /** * 获取GIF图片一帧图片 - 同步执行 * @param src * @param target * @param frame * @throws Exception */ public static boolean getGifOneFrame(String src, String target, int frame) throws Exception { if(!src.endsWith(".gif")){ return false; } createDirectory(target); IMOperation op = new IMOperation(); op.addImage(src + "["+frame+"]"); op.addImage(target); ConvertCmd cmd = (ConvertCmd) getImageCommand("convert"); cmd.setAsyncMode(false); cmd.run(op); return true; } /** * 获取GIF图片一帧图片 - 异步执行 * @param src * @param target * @param frame * @throws Exception */ public static void getGifOneFrameAsync(String src, String target, int frame) throws Exception { if(!src.endsWith(".gif")){ return; } createDirectory(target); IMOperation op = new IMOperation(); op.addImage(src + "["+frame+"]"); op.addImage(target); ConvertCmd cmd = (ConvertCmd) getImageCommand("convert"); cmd.setAsyncMode(true); cmd.run(op); } public static void main(String[] args) throws Exception { String src = "C:\\img\\2.jpg"; String target = "C:\\img\\3.jpg"; copyImage(src, target); logger.info("处理完成"); } }

    大家还可以参考我专栏中的其他文章:
    (1)Java图片处理 - 安装ImageMagick库使用convert命令
    (2)Java图片处理 - 创建工具类
    (3)Java图片处理 - 复制
    (4)Java图片处理 - 缩放图片
    (5)Java图片处理 - gif图获取一帧图片

    你可能感兴趣的:(图片处理,Java图片处理)