首頁 > 軟體

springboot實現瀏覽器截圖並新增文字

2022-02-11 10:01:16

最近接到一個新的需求,需要將管理系統中指定頁面進行截圖並將截圖後的圖片動態新增文字之後儲存到本地指定目錄。本文按照測試demo簡單記錄一下,此需求分成三個需求點進行實現:
    1.瀏覽器截圖生成圖片(儲存位置為伺服器指定目錄)
    2.截圖後的圖片新增文字
    3.伺服器圖片下載到使用者端本地指定目錄

1.瀏覽器截圖(phantomjs外掛實現)

 phantomjs外掛官方下載地址:https://phantomjs.org/download.html
    外掛組態檔目錄(windows環境使用phantomjs.exe,Linux使用phantomjs)

截圖測試demo:
檔案路徑獲取工具類:

@Component
public class FileResourceUtil {
    @Autowired
    private ResourceLoader resourceLoader;

    /**
     * 根據檔案名字獲取路徑
     * @param fileNameAndPath
     * @return
     */
    public String getFilePath(String fileNameAndPath) throws IOException {
        File file = resourceLoader.getResource("file:"+ fileNameAndPath).getFile();
        if(!file.exists()) {
            file = resourceLoader.getResource("classpath:"+ fileNameAndPath).getFile();
        }
        return file.getAbsolutePath();
    }
}

截圖介面:

public interface ScreenshotService {

    String screenshot(HttpServletRequest re, String url, String size) throws IOException;
}

截圖實現類:

@Service
public class ScreenshotServiceImpl implements ScreenshotService  {
	// 設定截圖後圖片儲存路徑
    private String pdfPath = "D:/testPhoto/";

    @Autowired
    private FileResourceUtil fileResourceUtil;


    @Override
    public String screenshot(HttpServletRequest re, String url, String size) throws IOException {
        String img = "";
        // 此處可根據作業系統獲取對應phantomjs檔案路徑(phantomjs.exe對應Windows,phantomjs對應Linux)
       /* String plugin = '';
        String os = System.getProperty("os.name").toLowerCase();
        if (os.contains("windows")) {
            plugin = resourceUtil.getFilePath("plugin/phantomjs.exe");
        }else{
         plugin = resourceUtil.getFilePath("plugin/phantomjs");
        }*/
        // 測試環境為window環境,故獲取phantomjs.exe所在目錄
          String plugin = fileResourceUtil.getFilePath("plugin/phantomjs.exe");
        String js = fileResourceUtil.getFilePath("plugin/rasterize.js");

        File file = new File(this.pdfPath);
        if (!file.exists()) {
            file.mkdirs();
        }

		// 截圖後檔名可自定義
        img = this.pdfPath  +  "1.png";

        File pluginFile = new File(plugin);
        if (!pluginFile.canExecute()) {
            pluginFile.setExecutable(true);
        }

        File jsFile = new File(js);

        if (!execute(plugin, jsFile.getAbsolutePath(), url, img, size)) {
            return null;
        }

        return img;
    }

	// 截圖圖片流處理
    public boolean execute(String... args) {

        Process process = null;

        StringBuilder msg = new StringBuilder();

        try {
            process = Runtime.getRuntime().exec(args);
            BufferedReader input = new BufferedReader(
                    new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = input.readLine()) != null) {
                System.out.println(line);
            }
            input.close();
        } catch (IOException e) {
            System.out.println("error:"+e.getCause());
            msg.append("error");
        }
        return !msg.toString().endsWith("error");
    }
}

測試:

@SpringBootTest
class DemoApplicationTests {

	@Autowired
	public ScreenshotServiceImpl screenshotService;

	@Test
	public void test1(){
		try {
		// 截圖圖片大小可根據實際需求進行設定
			screenshotService.screenshot(null, "https://www.baidu.com/" , "800px*800px");
		} catch (IOException e) {
			e.printStackTrace();
		}
}

截圖之後儲存圖片:

2.圖片上新增文字(提供兩種實現

方法一:

public class DemoOne {

    public static void main(String[] args) {
    	// 原檔案地址
        String filePath = "D:\testPhoto\1.png";
        // 儲存後檔案地址:
        String outPath = "D:\testPhoto\2.png";   


        drawTextInImg(filePath, "test", outPath, 60, 755, "black", 24.0f);//在圖片上加test
    }
    public static void drawTextInImg(String filePath, String text, String outPath,int left_n, int top_n,String color,float fsize) {
        ImageIcon imgIcon = new ImageIcon(filePath);
        Image img = imgIcon.getImage();
        int width = img.getWidth(null);
        int height = img.getHeight(null);
        BufferedImage bimage = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);

        Graphics2D g = bimage.createGraphics();

        int fontSize = (int)fsize;    //字型大小
        int rectX = left_n;
        int rectY = top_n;

        Font font = new Font("宋體",Font.BOLD, fontSize);   //定義字型
        g.setBackground(Color.white);
        g.drawImage(img, 0, 0, null);
        if("black".equals(color)){
            g.setPaint(Color.black);
        }else if("red".equals(color)){
            g.setPaint(Color.red);
        }
        g.setFont(font);
        g.drawString(text, rectX, top_n);
        g.dispose();

        try {
            FileOutputStream out = new FileOutputStream(outPath);
            ImageIO.write(bimage, "png", out);
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

簡單新增文字:

方法2:

public class DemoTwo {
    public void addWaterMark(String srcImgPath, String tarImgPath, String waterMarkContent,Color markContentColor,Font font) {

        try {
            // 讀取原圖片資訊
            File srcImgFile = new File(srcImgPath);//得到檔案
            Image srcImg = ImageIO.read(srcImgFile);//檔案轉化為圖片
            int srcImgWidth = srcImg.getWidth(null);//獲取圖片的寬
            int srcImgHeight = srcImg.getHeight(null);//獲取圖片的高
            // 加水印
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();
            g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
            g.setColor(markContentColor); //根據圖片的背景設定水印顏色
            g.setFont(font);              //設定字型

            //設定水印的座標
            int x = srcImgWidth - 2*getWatermarkLength(waterMarkContent, g);
            int y = srcImgHeight - 2*getWatermarkLength(waterMarkContent, g);
            g.drawString(waterMarkContent, x, y);  //畫出水印
            g.dispose();
            // 輸出圖片
            FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
            ImageIO.write(bufImg, "png", outImgStream);
            System.out.println("新增水印完成");
            outImgStream.flush();
            outImgStream.close();

        } catch (Exception e) {
            // TODO: handle exception
        }
    }
    public int getWatermarkLength(String waterMarkContent, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    }
    public static void main(String[] args) {
        Font font = new Font("微軟雅黑", Font.PLAIN, 35);                     //水印字型
        String srcImgPath="D:\testPhoto\1.png"; //源圖片地址
        String tarImgPath="D:\testPhoto\3.png"; //待儲存的地址
        String waterMarkContent="2022北京冬奧會";  //水印內容
        Color color=new Color(135,206,235,128);                              //水印圖片色彩以及透明度
        new WaterMarkUtils().addWaterMark(srcImgPath, tarImgPath,  waterMarkContent,color,font);

    }
}

新增之後圖片:

3.圖片下載到本地指定路徑

    注意,這裡的下載選擇目錄是通過設定響應的contentType實現,並非通過前端標籤實現。下載目錄選擇頁面如下(檔名可動態設定):

測試demo:

@RestController
public class DownLoad {

    @GetMapping("/down")
    public void down(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 圖片所在伺服器目錄
        String filePath = "圖片所在伺服器目錄";
        
        // 建立檔案物件
        File file = new File(filePath);
        FileInputStream fileInputStream = new FileInputStream(file);
        //設定Http響應頭告訴瀏覽器下載圖片,下載的圖片名也是在這裡設定
        response.setHeader("Content-Disposition", "attachment;Filename=自定義設定圖片名.png");
        OutputStream outputStream = response.getOutputStream();
        byte[] bytes = new byte[2048];
        int len = 0;
        while ((len = fileInputStream.read(bytes))>0){
            outputStream.write(bytes,0,len);
        }
        fileInputStream.close();
        outputStream.close();
    }
}

總結

到此這篇關於springboot實現瀏覽器截圖並新增文字的文章就介紹到這了,更多相關springboot瀏覽器截圖內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com