java,springboot + thymeleaf 上傳圖片、刪除圖片到伺服器、本地,壓縮圖片上傳(有些圖片會失真),原圖上傳

小園子1346513發表於2020-12-06

0、共公部分

0.1 專案結構

在這裡插入圖片描述

0.2 pom檔案

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.4.0</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.gh</groupId>
	<artifactId>thymeleafPictureDemo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>thymeleafPictureDemo</name>
	<description>springboot結合thymeleaf上傳圖片、刪除圖片,伺服器和本地</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.5</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

0.3 application.yml檔案

server:
  port: 9098

spring:
  mvc:
    # 訪問靜態資源地址
    static-path-pattern: /static/**
  web:
    resources:
      # 設定靜態資源包的路徑
      static-locations: classpath:/static

0.4 controller檔案

0.4.1 imageUploadController

package com.gh.thymeleafPictureDemo.controller;

import com.gh.thymeleafPictureDemo.util.Result;
import com.gh.thymeleafPictureDemo.util.UploadImageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * 圖片上傳
 * @author gh
 * @date 2020/12/5
 */
@CrossOrigin("*")
@RestController
@RequestMapping("/api")
@Slf4j
public class imageUploadController {

    /**
     * 上傳圖片測試
     * @return
     */
    @RequestMapping("/upload")
    public Result<String> uploadImage(MultipartFile file){
        Result result = new Result<>();
        result.setCode(1);
        result.setData("資料");
        String imagePath = UploadImageUtil.uploadImage(file);
        if(imagePath.length() > 0){
            result.setMsg(imagePath);
            return result;
        }
        result.setMsg("上傳失敗");
        return result;
    }

    /**
     * 刪除圖片
     * @param path
     * @return
     */
    @RequestMapping("/deleteFile")
    public Result<String> uploadImage(String path){
        Result result = new Result<>();
        result.setCode(1);
        result.setData("資料");
        log.info("圖片路徑" + path);
        if(UploadImageUtil.deleteImage(path)){
            result.setMsg("刪除成功");
            return result;
        }
        result.setMsg("刪除失敗");
        return result;
    }


}

0.4.2 pageController

package com.gh.thymeleafPictureDemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author gh
 * @date 2020/12/6
 */
@Controller
public class pageController {
    /**
     * thymeleaf跳轉到image.html頁面
     * @return 介面
     */
    @RequestMapping("/")
    public String mixPage(){
        return "image";
    }
}

0.5 部分uitl檔案

0.5.1 FileUtil

package com.gh.thymeleafPictureDemo.util;

import java.io.File;
import java.io.FileOutputStream;

/**
 * @author gh
 * @date 2020/12/5
 */
public class FileUtil {
    public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {
        File targetFile = new File(filePath);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        FileOutputStream out = new FileOutputStream(filePath + fileName);
        out.write(file);
        out.flush();
        out.close();
    }
}

0.5.2 ImageUtil

package com.gh.thymeleafPictureDemo.util;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;

/**
 * 圖片上傳需要,將圖片轉換
 * @author gh
 * @date 2020/11/25
 */
public class ImageUtil {

    public static BufferedImage change2jpg(File f) {
        try {
            Image i = Toolkit.getDefaultToolkit().createImage(f.getAbsolutePath());
            PixelGrabber pg = new PixelGrabber(i, 0, 0, -1, -1, true);
            pg.grabPixels();
            int width = pg.getWidth(), height = pg.getHeight();
            final int[] RGB_MASKS = { 0xFF0000, 0xFF00, 0xFF };
            final ColorModel RGB_OPAQUE = new DirectColorModel(32, RGB_MASKS[0], RGB_MASKS[1], RGB_MASKS[2]);
            DataBuffer buffer = new DataBufferInt((int[]) pg.getPixels(), pg.getWidth() * pg.getHeight());
            WritableRaster raster = Raster.createPackedRaster(buffer, width, height, width, RGB_MASKS, null);
            BufferedImage img = new BufferedImage(RGB_OPAQUE, raster, false, null);
            return img;
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

    public static void resizeImage(File srcFile, int width,int height, File destFile) {
        try {
            if(!destFile.getParentFile().exists()) {
                destFile.getParentFile().mkdirs();
            }
            Image i = ImageIO.read(srcFile);
            i = resizeImage(i, width, height);
            ImageIO.write((RenderedImage) i, "jpg", destFile);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static Image resizeImage(Image srcImage, int width, int height) {
        try {

            BufferedImage buffImg = null;
            buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            buffImg.getGraphics().drawImage(srcImage.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);

            return buffImg;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

}

0.5.3 Result

package com.gh.thymeleafPictureDemo.util;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * 通用介面返回型別,這裡不僅僅可以用T
 * 隨便用什麼都可以的
 * @author gh
 * @date 2020/11/19
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> implements Serializable {
    int code;
    T data;
    String msg;
    private static final long serialVersionUID = 1L;
}

1、原圖上傳

其實就是UploadImageUtil不同而已

1.1 本地上傳

這裡因為要放在target目錄下,所以本地和伺服器不能用同一個函式,,,這裡可能還有解決辦法,但是我暫時沒有找到,如果有老哥可以找到可以討論一下,嘿嘿

   /**
     * 刪除圖片函式,本地用
     * @param imagePath 這個是圖片名字的完整路徑
     * @return 結果
     */
    public static boolean deleteImage(String imagePath){
        try {
            imagePath = URLDecoder.decode((ResourceUtils.getURL("classpath:").getPath()) + imagePath, System.getProperty("file.encoding"));
            File file = new File(imagePath);
            log.info("刪除圖片");
            log.info(imagePath);
            // 刪除圖片
            file.delete();
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 上傳圖片函式,本地用
     * @param file 圖片檔案
     * @return
     */
    public static String uploadImage(MultipartFile file){
        // 獲取唯一的uuid
        String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        try {
            String filePath = URLDecoder.decode((ResourceUtils.getURL("classpath:").getPath()+"static/img/"), System.getProperty("file.encoding"));
            FileUtil.uploadFile(file.getBytes(), filePath, uuid + ".jpg");
            log.info("上傳圖片");
            log.info(filePath + uuid + ".jpg");
            return "/static/img/" + uuid + ".jpg";
        } catch (Exception e) {
            // 上傳失敗
            return "";
        }
    }

1.2 上傳到伺服器

這裡要注意,因為用了nginx反向代理,所以,訪問的時候要配置靜態資源訪問
在這裡插入圖片描述
nginx配置偽靜態,這樣就能訪問到image目錄下的圖片了
在這裡插入圖片描述

 /**
     * 上傳圖片函式,伺服器用的
     * @param file 圖片檔案
     * @return
     */
    public static String uploadImage(MultipartFile file){
        // 獲取唯一的uuid
//        String filePath = URLDecoder.decode(Objects.requireNonNull(Objects.requireNonNull(ClassUtils.getDefaultClassLoader()).getResource("")).getPath()) + "static/img/";
        String filePath = "image/";
        String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        log.info("圖片路徑" + filePath);
        try {
            FileUtil.uploadFile(file.getBytes(), filePath, uuid + ".jpg");
            log.info("上傳圖片");
            log.info(filePath + uuid + ".jpg");
            return "/" + filePath + uuid + ".jpg";
        } catch (Exception e) {
            // 上傳失敗
            return "";
        }
    }

    /**
     * 刪除圖片函式,伺服器用的
     * @param imagePath 這個是圖片名字的完整路徑
     * @return 結果
     */
    public static boolean deleteImage(String imagePath){
        try {
            // 去除第一個字串,不然伺服器哪裡刪除不了圖片
            imagePath = imagePath.substring(1);
            File file = new File(imagePath);
            log.info("刪除圖片");
            log.info(imagePath);
            // 刪除圖片
            file.delete();
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

2、壓縮上傳

這裡主要是靠ImageUtil檔案,但是這個檔案我是在網上找的,發現有些圖片會失真,,,但是大部分還是有用的

2.1 本地上傳

/**
     * 刪除圖片函式,本地用
     * @param imagePath 這個是圖片名字的完整路徑
     * @return 結果
     */
    public static boolean deleteImage(String imagePath){
        try {
              log.info("刪除圖片");
              log.info(imagePath);
            imagePath = URLDecoder.decode((ResourceUtils.getURL("classpath:").getPath()) + imagePath, System.getProperty("file.encoding"));
            File file = new File(imagePath);
            // 刪除圖片
            file.delete();
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 上傳圖片函式,本地用
     * @param file 圖片檔案
     * @return 結果
     */
    public static String uploadImage(MultipartFile file){
        // 獲取唯一的uuid
        String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        try {
            // 獲取圖片儲存的完整路徑
            String path1 = URLDecoder.decode((ResourceUtils.getURL("classpath:").getPath()+"static/img/"), System.getProperty("file.encoding"));
            String imagePath = path1 + uuid + ".jpg";
            log.info("上傳圖片");
            log.info(imagePath);
            // 獲取要上傳圖片的目錄,同時解碼
            File imageFolder = new File(URLDecoder.decode(path1, System.getProperty("file.encoding")));
            if(!imageFolder.exists()){
                // 先檢查這個目錄是否存在
                imageFolder.mkdirs();
            }
            // new一個圖片檔案
            File fileImage = new File(imageFolder, uuid + ".jpg");
            if (!fileImage.isFile()) {
                // 如果不存在這個檔案
                fileImage.createNewFile();
            }
            FileUtils.copyInputStreamToFile(file.getInputStream(), fileImage);
            BufferedImage img = ImageUtil.change2jpg(fileImage);
            ImageIO.write(img, "jpg", fileImage);
            // 返回圖片的相對路徑
            return "/static/img/" + uuid + ".jpg";
        }catch (Exception e){
            e.printStackTrace();
            // 上傳圖片失敗就返回一個長度為0的空字串
            return "";
        }
    }

2.2 上傳圖片到伺服器

和上面一樣要配置nginx靜態資源

 /**
     * 上傳圖片函式,伺服器用的
     * @param file 圖片檔案
     * @return
     */
    public static String uploadImage(MultipartFile file){
        // 獲取唯一的uuid
        String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        try {
            // 獲取圖片儲存的完整路徑
            String path1 = "image/";
            String imagePath = path1 + uuid + ".jpg";
            log.info("上傳圖片");
            log.info(imagePath);
            // 獲取要上傳圖片的目錄,同時解碼
            File imageFolder = new File(URLDecoder.decode(path1, System.getProperty("file.encoding")));
            if(!imageFolder.exists()){
                // 先檢查這個目錄是否存在
                imageFolder.mkdirs();
            }
            // new一個圖片檔案
            File fileImage = new File(imageFolder, uuid + ".jpg");
            if (!fileImage.isFile()) {
                // 如果不存在這個檔案
                fileImage.createNewFile();
            }
            FileUtils.copyInputStreamToFile(file.getInputStream(), fileImage);
            BufferedImage img = ImageUtil.change2jpg(fileImage);
            ImageIO.write(img, "jpg", fileImage);
            // 返回圖片的相對路徑
            return "/image/" + uuid + ".jpg";
        }catch (Exception e){
            e.printStackTrace();
            // 上傳圖片失敗就返回一個長度為0的空字串
            return "";
        }
    }

    /**
     * 刪除圖片函式,伺服器用的
     * @param imagePath 這個是圖片名字的完整路徑
     * @return 結果
     */
    public static boolean deleteImage(String imagePath){
        try {
            imagePath = imagePath.substring(1);
            log.info("刪除圖片");
            log.info(imagePath);
            File file = new File(imagePath);
            // 刪除圖片
            file.delete();
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

如果覺得有用,各位觀眾老爺點個贊再走哈~謝謝(其實再加個關注也不介意哈哈哈)

相關文章