Java图片处理 - 创建工具类

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chwshuang/article/details/64923345

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.im4java</groupId>
            <artifactId>im4java</artifactId>
            <version>1.4.0</version>
        </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<String> 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);
    }

    /**
     * <pre>
     * <li>去除Exif信息</li>
     * <li>按指定的宽度等比缩放图片</li>
     * <li>降低图片品质</li>
     * <li>将图片分割分指定高度的小图</li>
     *
     * @param path 原文件路径
     * @param des 目标文件路径
     * @param width 指定宽度
     * @param subImageHeight 指定高度
     * @param quality 保留品质
     * @return 小图路径
     * @throws Exception
     * </pre>
     */
    public static List<String> 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<String> 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<String> fileList = new ArrayList<String>();
        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图获取一帧图片

猜你喜欢

转载自blog.csdn.net/chwshuang/article/details/64923345