1. 程式人生 > >JAVA上傳影象時影象處理的基本方法

JAVA上傳影象時影象處理的基本方法

一,form表單型別

<form id="xxForm" action="xx.htm" method="post" enctype ="multipart/form-data" >

則請求頭含有:

formdata-----------------------------14471729621574Content-Disposition: form-data; name="Filedata"; filename="11.jpg"Content-Type: image/jpeg

二,檔案大小控制(3M)

MultipartFile file = ((MultipartHttpServletRequest) request).getFile("Filedata");

if (file == null || file.getSize() >= 3 * 1024 * 1024) {

    showErrorMsg();

}


三,檔案字尾名控制

直接使用MultipartFile file 的getOriginalFilename()方法,獲取到的中文名稱可能是亂碼。建議單獨傳參fileName

String suffix = StringUtil.substringAfterLast(fileName, ".").toLowerCase();
        if (!suffix.matches(IMAGE_TYPE)) {

           showErrorMsg();

       }

private static final String                       IMAGE_TYPE             = "(jpg|jpeg|png)";


四,檔案安全檢查

以上三種類型都應該可以正常轉換為jpg檔案

try {
            src = ImageIO.read(infile.getInputStream());
        } catch (IOException e) {
            throw e;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

ImageIO.write(src, "jpg", baos);


五,圖片裁剪,縮放

/**
     * 裁剪圖片
     *
     * @param in
     * @param out
     * @param format (jpg,jpeg,png)
     * @param x 擷取後的x座標
     * @param y 擷取後的y座標
     * @param width 擷取後的寬度
     * @param height 擷取後的高度
     * @param orgWidth 圖片寬度
     * @param orgHeight 圖片高度
     */
    public static void clipPic(ByteArrayInputStream in, ByteArrayOutputStream out, String format,
                               int x, int y, int width, int height, int orgWidth, int orgHeight) {
        try {
            LoggerUtil.info(LOGGER, "[PicCompress]開始裁減圖片! ");

            BufferedImage tag = ImageIO.read(in);
            BufferedImage oute = null;
            int sourceWidth = tag.getWidth();
            int sourceHeight = tag.getHeight();
            if (width >= orgWidth && height >= orgHeight) {
                oute = tag.getSubimage(0, 0, sourceWidth, sourceHeight);
            } else {
                double rateW = (double) sourceWidth / (double) orgWidth;
                double rateH = (double) sourceHeight / (double) orgHeight;
                int targetWidth = (int) ((width < orgWidth ? width : orgWidth) * rateW);
                int targetHeight = (int) ((height < orgHeight ? height : orgHeight) * rateH);
                int targetX = (int) (x * rateW);
                int targetY = (int) (y * rateH);
                oute = tag.getSubimage(targetX, targetY, targetWidth, targetHeight);
            }
            //儲存新圖片  
            ImageIO.write(oute, format, out);
        } catch (IOException e) {
            LoggerUtil.warn(LOGGER, "[PicCompress]裁減圖片失敗! ", e);
        }
    }

六,圖片壓縮

public static void compressPic(ByteArrayInputStream in, ByteArrayOutputStream out,
                                   String format, int size, int limitSize) {

        try {
            BufferedImage img = ImageIO.read(in);
            double rate = (double) limitSize / (double) size;
            int width = (int) (img.getWidth() * rate);
            int height = (int) (img.getHeight() * rate);
            BufferedImage tag = null;
            if (StringUtil.equals(format, "png")) {
                tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            } else {
                tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            }

            tag.getGraphics().drawImage(img.getScaledInstance(width, height, Image.SCALE_SMOOTH),
                0, 0, null);

            //儲存新圖片  
            ImageIO.write(tag, format, out);
        } catch (IOException e) {
            LoggerUtil.warn(LOGGER, "[PicCompress]壓縮圖片大小失敗! ", e);
        }
    }

七,其他流處理工具

轉換

/**
     * 從輸入流讀取內容, 寫入到輸出流中.  使用指定大小的緩衝區.
     *
     * @param in 輸入流
     * @param out 輸出流
     * @param bufferSize 緩衝區大小(位元組數)
     *
     * @throws IOException 輸入輸出異常
     */
    public static void io(InputStream in, OutputStream out, int bufferSize)
            throws IOException {
        if (bufferSize == -1) {
            bufferSize = DEFAULT_BUFFER_SIZE;
        }

        byte[] buffer = new byte[bufferSize];
        int    amount;

        while ((amount = in.read(buffer)) >= 0) {
            out.write(buffer, 0, amount);
        }
    }
private static final int DEFAULT_BUFFER_SIZE = 8192;

關閉,應當在finally中執行

/**
     * 安全的關閉流
     * @param <T>
     * @param stream
     */
    public static <T extends Closeable> void closeStreamSafely(T stream) {
        if (stream == null) {
            return;
        }
        try {
            stream.close();
        } catch (IOException e) {
            //ignore
        }
    }

同步化的輸出流

/**
     * 同步化的輸出流包裹器.
     */
    private static class SynchronizedOutputStream extends OutputStream {
        private OutputStream out;
        private Object       lock;

        SynchronizedOutputStream(OutputStream out) {
            this(out, out);
        }

        SynchronizedOutputStream(OutputStream out, Object lock) {
            this.out      = out;
            this.lock     = lock;
        }

        public void write(int datum) throws IOException {
            synchronized (lock) {
                out.write(datum);
            }
        }

        public void write(byte[] data) throws IOException {
            synchronized (lock) {
                out.write(data);
            }
        }

        public void write(byte[] data, int offset, int length)
                throws IOException {
            synchronized (lock) {
                out.write(data, offset, length);
            }
        }

        public void flush() throws IOException {
            synchronized (lock) {
                out.flush();
            }
        }

        public void close() throws IOException {
            synchronized (lock) {
                out.close();
            }
        }
    }