欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java基于Graphics2D實(shí)現(xiàn)海報(bào)制作

 更新時(shí)間:2024年04月26日 10:59:02   作者:凌晨的集市人很少  
這篇文章主要為大家詳細(xì)介紹了Java如何基于Graphics2D實(shí)現(xiàn)海報(bào)制作,并且支持自定義顏色,背景,logo,貼圖,感興趣的小伙伴可以了解一下

效果

海報(bào)一

海報(bào)二

代碼

參數(shù)實(shí)體類

package com.ly.cloud.dto;
 
import lombok.Data;
 
/**
 * @Author  
 * @Date  Created in  2024/4/24 下午2:16
 * @DESCRIPTION:   海報(bào)頁面所需的參數(shù) 實(shí)體類
 * @Version  V1.0
 */
@Data
public class PosterTemplateDto {
    /**
     * 用來判斷是不是 需要把數(shù)據(jù)寫死 0 寫死的對象,1 自己傳的
     */
    private String id;
    {
        id = "0";
    }
    /**
     * 海報(bào)編號(hào)  0: 橫向海報(bào)   1: 豎向海報(bào)
     */
    private String posterId;
 
    /**
     * 海報(bào)顏色 0: 綠色  1: 藍(lán)色  2: 紅色
     */
    private String posterColor;
    /**
     * 海報(bào)背景圖片名稱
     */
    private String posterBackImage;
 
    /**
     * 海報(bào)logo
     */
    private String posterLogo;
    /**
     * 海報(bào)主題  xxxx 第 x 期
     */
    private String posterTopic;
 
    /**
     * 海報(bào)標(biāo)題
     */
    private String posterTitle;
 
    /**
     * 海報(bào)年份
     */
    private String posterYear;
 
    /**
     * 海報(bào)具體時(shí)間  幾月幾號(hào)
     */
    private String posterMonth;
 
    /**
     * 海報(bào)具體時(shí)間 14:30 ~ 15:30(周四)
     */
    private String posterDay;
 
    /**
     * 講座就行校區(qū)
     */
    private String posterSchool;
    /**
     * 講座的具體地址
     */
    private String posterAddress;
 
    /**
     * 講座主講人
     */
    private String posterMainSpeaker;
 
    /**
     * 主講人個(gè)人詳細(xì)信息介紹
     */
    private String posterPeopleDetail;
 
    /**
     * 主持人
     */
    private String mainPeople;
}

工具類

FileUtil.java

package com.ly.cloud.util;
 
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import org.springframework.web.multipart.MultipartFile;
 
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
 
/**
 * @Author  
 * @Date  Created in  2024/4/11 上午11:13
 * @DESCRIPTION:   將 multipartFile --> file
 * @Version  V1.0
 */
public class FileUtil {
 
    private final static Log logger = LogFactory.getLog(FileUtil.class);
 
 
    /**
     * 將 multipartFile -->  fileInputStream
     */
    public static FileInputStream convertMultipartFileToInputStream(MultipartFile multipartFile) throws IOException {
        // 創(chuàng)建臨時(shí)文件
        File tempFile = File.createTempFile("temp", null);
 
        // 將MultipartFile的數(shù)據(jù)寫入臨時(shí)文件
        try (FileOutputStream fos = new FileOutputStream(tempFile)) {
            fos.write(multipartFile.getBytes());
        }
 
        // 將臨時(shí)文件轉(zhuǎn)換為FileInputStream
        FileInputStream fileInputStream = new FileInputStream(tempFile);
 
        // 刪除臨時(shí)文件
        tempFile.delete();
 
        return fileInputStream;
    }
 
    /**
     * 將上傳的 logo圖片保存在本地;
     */
    public static File convertInputStreamToFile(InputStream inputStream,String fileName) throws IOException {
        // 創(chuàng)建圖片文件
        String resourcesPath = new File("src/main/resources/").getAbsolutePath();
        // 拼接images目錄的路徑
        String imagesPath = resourcesPath + "/static/imagesLogo/"; // 這里的static是resources目錄下的一個(gè)示例子目錄,你可以根據(jù)實(shí)際情況修改
        logger.info("我的路徑是:{}"+imagesPath);
        File directory = new File(imagesPath);
        // 如果目標(biāo)文件夾不存在,則創(chuàng)建它
        if (!directory.exists()) {
            directory.mkdirs();
        }
        File file = new File(directory, fileName);
        try (OutputStream outputStream = Files.newOutputStream(file.toPath())) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, length);
            }
        }
//        deleteImage(imagesPath,fileName);
        return file;
    }
 
    /**
     * 刪除圖片
     */
    public static void deleteImage(String directoryPath, String imageName) {
        File directory = new File(directoryPath);
        if (!directory.exists() || !directory.isDirectory()) {
            return;
        }
        File imageFile = new File(directory, imageName);
        if (imageFile.exists() && imageFile.isFile()) {
            if (imageFile.delete()) {
                logger.info("刪除圖片成功!");
            } else {
                logger.error("刪除圖片失?。?);
            }
        } else {
            System.out.println("Image file " + imageName + " does not exist.");
        }
    }
 
    /**
     * 修改圖片的寬高 等比例擴(kuò)大 海報(bào)背景圖和 logo
     */
    public static byte[] resizeImage(byte[] imageData, int width, int height) throws IOException {
        ByteArrayInputStream bis = new ByteArrayInputStream(imageData);
        BufferedImage image = ImageIO.read(bis);
 
        Image resizedImage = image.getScaledInstance(width, height, Image.SCALE_SMOOTH);
 
        BufferedImage bufferedResizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        bufferedResizedImage.getGraphics().drawImage(resizedImage, 0, 0, null);
 
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ImageIO.write(bufferedResizedImage, "jpg", bos);
        byte[] resizedImageData = bos.toByteArray();
 
        bis.close();
        bos.close();
 
        return resizedImageData;
    }
//    public static void main(String[] args) throws IOException {
//        String resourcesPath = new File("src/main/resources/").getAbsolutePath();
//        // 拼接images目錄的路徑
//        String imagesPath = resourcesPath + "/static/images/"; // 這里的static
//
//        // 讀取背景圖片
//        BufferedImage backgroundImage = ImageIO.read(new File(imagesPath + "/" + "4c9a599ae920240424112637.png"));
//        ImageIO.write(backgroundImage, "PNG", new File("D:\\test1\\image.png"));
//
//    }
}

PosterUtil.java 

package com.ly.cloud.util;
 
import sun.font.FontDesignMetrics;
 
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
 
/**
 * @Author  
 * @Date  Created in  2024/4/24 下午2:45
 * @DESCRIPTION:    海報(bào)工具類
 * @Version  V1.0
 */
 
public class PosterUtil {
 
    /**
     * 從新設(shè)置海報(bào)圖片的寬和高
     * @param originalImage 原始圖片
     * @param targetWidth 寬
     * @param targetHeight 高
     * @return BufferedImage
     */
    public static BufferedImage scaleImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
        int type = originalImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : originalImage.getType();
        BufferedImage scaledImage = new BufferedImage(targetWidth, targetHeight, type);
        Graphics2D g = scaledImage.createGraphics();
        // Calculate the ratio between the original and scaled image size
        double scaleX = (double) targetWidth / originalImage.getWidth();
        double scaleY = (double) targetHeight / originalImage.getHeight();
        double scale = Math.min(scaleX, scaleY);
        // Now we perform the actual scaling
        int newWidth = (int) (originalImage.getWidth() * scale);
        int newHeight = (int) (originalImage.getHeight() * scale);
        int x = (targetWidth - newWidth) / 2;
        int y = (targetHeight - newHeight) / 2;
        g.drawImage(originalImage.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH), x, y, null);
        g.dispose();
        return scaledImage;
    }
 
    /**
     * @Author  
     * @Description  海報(bào)橫向文字寫字換行算法
     * @Date  18:08 2024/4/24
     * @Param 參數(shù) Graphics2D 對象 、font 字體設(shè)置 、 文字、 x軸左邊、 y軸坐標(biāo) 、每行字體的換行寬度
     **/
    public static void drawWordAndLineFeed(Graphics2D g2d, Font font, String words, int wordsX, int wordsY, int wordsWidth) {
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
        // 獲取字符的最高的高度
        int height = metrics.getHeight();
 
        int width = 0;
        int count = 0;
        int total = words.length();
        String subWords = words;
        int b = 0;
        for (int i = 0; i < total; i++) {
            // 統(tǒng)計(jì)字符串寬度 并與 預(yù)設(shè)好的寬度 作比較
            if (width <= wordsWidth) {
                width += metrics.charWidth(words.charAt(i)); // 獲取每個(gè)字符的寬度
                count++;
            } else {
                // 畫 除了最后一行的前幾行
                String substring = subWords.substring(0, count);
                g2d.drawString(substring, wordsX, wordsY + (b * height));
                subWords = subWords.substring(count);
                b++;
                width = 0;
                count = 0;
            }
            // 畫 最后一行字符串
            if (i == total - 1) {
                g2d.drawString(subWords, wordsX, wordsY + (b * height));
            }
        }
    }
 
    /**
     * 將上傳的個(gè)人頭像裁剪成對應(yīng)的海報(bào)比例的頭像,并裁剪成圓形
     * @param image 讀取的頭像找
     * @param size  寬高大小像素
     * @return BufferedImage
     */
    public static BufferedImage resizeAndClipToCircle(BufferedImage image, int size) {
        // 縮小圖片
        BufferedImage resizedImage = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = resizedImage.createGraphics();
        g2d.drawImage(image, 0, 0, size, size, null);
        g2d.dispose();
 
        // 裁剪成圓形
        BufferedImage circularImage = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d2 = circularImage.createGraphics();
        Ellipse2D.Double ellipse = new Ellipse2D.Double(0, 0, size, size);
        g2d2.setClip(ellipse);
        g2d2.drawImage(resizedImage, 0, 0, size, size, null);
        g2d2.dispose();
 
        return circularImage;
    }
 
    /**
     * 部分文字 垂直排序時(shí),不滿多列,最后一列居中顯示
     * @param textGraphics Graphics 對象
     * @param text  要傳入的海報(bào)描述
     */
    public static void drawMyString(Graphics textGraphics, String text,Color color) {
 
        // 每列顯示的漢字?jǐn)?shù)量
        int columnSize = 7;
        // 文字之間的垂直間距
        int verticalSpacing = 75;
 
        // 獲取字體渲染上下文
        FontMetrics fm = textGraphics.getFontMetrics();
        // 獲取字體的高度
        int fontHeight = fm.getHeight();
        System.out.println(fontHeight);
        // 計(jì)算每列的寬度
        int columnWidth = fontHeight + verticalSpacing;
 
        // 設(shè)置初始位置
        int x = 280;
        int y = 450;
        Font fontFour = new Font(" Source Han Sans CN", Font.BOLD, 100);
        textGraphics.setFont(fontFour);
        textGraphics.setColor(color);
        // 繪制文字
        int charCount = 0;
        int totalColumns = (int)Math.ceil((double)text.length() / columnSize); // 總列數(shù)
        int totalRows = Math.min(columnSize, text.length()); // 總行數(shù)
        int remainingChars = text.length() % columnSize; // 最后一列剩余字符數(shù)
 
        for (int columnIndex = 0; columnIndex < totalColumns; columnIndex++) {
            for (int rowIndex = 0; rowIndex < totalRows; rowIndex++) {
                if (charCount >= text.length()) break;
                char ch = text.charAt(charCount);
                 // 計(jì)算當(dāng)前位置
                int cx = x - columnIndex * columnWidth;
                int cy = y + rowIndex * fontHeight + rowIndex * verticalSpacing; // 加入垂直偏移量
                 // 計(jì)算當(dāng)前位置
//                int cx = x - columnIndex * columnWidth;
//                int cy = y + rowIndex * fontHeight + rowIndex * verticalSpacing + columnIndex ;
 
                // 如果是最后一列并且不滿 7 個(gè)字符,則需要將剩余字符居中
                if (columnIndex == totalColumns - 1 && remainingChars > 0) {
                    int extraVerticalSpace = (columnSize - remainingChars) * (fontHeight + verticalSpacing) / 2;
                    cy += extraVerticalSpace;
                }
                // 繪制文字
                textGraphics.drawString(String.valueOf(ch), cx, cy);
                charCount++;
            }
        }
    }
 
    /**
     * 橫向顯示 垂直文字
     * @param textGraphics Graphics 對象
     * @param text   顯示的 內(nèi)容
     * @param number 沒列顯示漢字?jǐn)?shù)量
     */
    public static void drawString(Graphics textGraphics,String text,int number){
 
        // 每列顯示的漢字?jǐn)?shù)量
        int columnSize = number;
        // 文字之間的垂直間距
        int verticalSpacing = 50;
 
        // 獲取字體渲染上下文
        FontMetrics fm = textGraphics.getFontMetrics();
        // 獲取字體的高度
        int fontHeight = fm.getHeight();
 
        // 計(jì)算每列的寬度
        int columnWidth = fontHeight + verticalSpacing;
 
        // 設(shè)置初始位置
        int x = 0;
        int y = 0;
        switch (number) {
            case 3:
                x = 1250;
                y = 790;
                break;
            case 10:
                x = 1150;
                y = 800;
                break;
            // 可以添加更多的條件分支
            default:
                // 默認(rèn)情況下的坐標(biāo)設(shè)置
                break;
        }
        if (number == 10) {
            Font fontFour = new Font(text, Font.BOLD, 60);
            textGraphics.setFont(fontFour);
            textGraphics.setColor(Color.WHITE);
        }
        // 繪制文字
        for (int i = 0; i < text.length(); i++) {
 
            char ch = text.charAt(i);
            // 計(jì)算當(dāng)前位置
            int cx = x - (i / columnSize) * columnWidth;
            int cy = y + (i % columnSize) * fontHeight;
            // 繪制文字
            textGraphics.drawString(String.valueOf(ch), cx, cy);
        }
    }
 
    public static void drawCenteredText(Graphics graphics, String text, int oneY, int twoY) {
        // 設(shè)置字體和顏色
        Font font = new Font("宋體", Font.BOLD, 50);
        graphics.setFont(font);
        graphics.setColor(Color.WHITE);
        // 獲取字體渲染上下文
        FontMetrics fm = graphics.getFontMetrics(font);
        // 截取第二行文字的部分
        String textTwo = text.substring(text.indexOf("第"));
        // 獲取第一行文字的寬度
        String textOne = text.substring(0, text.indexOf("第"));
        // 獲取第二行文字的寬度
        int textTwoWidth = fm.stringWidth(textTwo);
        // 計(jì)算第一行文字的起始x坐標(biāo),使其水平居中
        int oneX = 50;
        // 計(jì)算第二行文字的起始x坐標(biāo),使其水平居中
        int twoX = (450 - textTwoWidth) / 2;
        // 繪制第一行文字
        graphics.drawString(textOne, oneX, oneY);
        // 繪制第二行文字
        graphics.drawString(textTwo, twoX, twoY);
    }
    /**
     * 在Graphics2D對象上繪制豎排文字
     *
     * @param textGraphics     Graphics2D對象
     * @param text            要繪制的文字
     */
    public static void drawMyLectureString(Graphics textGraphics, String text) {
 
        // 每列顯示的漢字?jǐn)?shù)量
        int columnSize = 25;
        // 文字之間的垂直間距
        int verticalSpacing = 1;
 
        // 獲取字體渲染上下文
        FontMetrics fm = textGraphics.getFontMetrics();
        // 獲取字體的高度
        int fontHeight = fm.getHeight() - 30;
 
        // 計(jì)算每列的寬度
        int columnWidth = fontHeight + verticalSpacing;
 
        // 設(shè)置初始位置
        int x = 800;
        int y = 190;
        Font fontFour = new Font("宋體", Font.BOLD, 40);
        textGraphics.setFont(fontFour);
        textGraphics.setColor(Color.WHITE);
 
        // 計(jì)算總列數(shù)
        int totalColumns = (int) Math.ceil((double) text.length() / columnSize); // 總列數(shù)
 
        // 繪制文字
        int charCount = 0;
        for (int rowIndex = 0; rowIndex < columnSize; rowIndex++) {
            for (int columnIndex = 0; columnIndex < totalColumns; columnIndex++) {
                int charIndex = rowIndex * totalColumns + columnIndex;
                if (charIndex >= text.length()) break;
                char ch = text.charAt(charIndex);
                // 計(jì)算當(dāng)前位置
                int cx = x - columnIndex * columnWidth;
                int cy = y + rowIndex * fontHeight + rowIndex * verticalSpacing; // 加入垂直偏移量
                // 繪制文字
                textGraphics.drawString(String.valueOf(ch), cx, cy);
            }
        }
    }
 
 
    /**
     * 字體傾斜
     */
    public static void qinxie(Font fontMonth,Graphics2D graphics){
        // 創(chuàng)建 AffineTransform 對象
        AffineTransform month = new AffineTransform();
        // 設(shè)置水平傾斜
        month.shear(-0.2, 0); // + 向左  -  向右傾斜
        // 應(yīng)用變換到字體
        fontMonth = fontMonth.deriveFont(month);
        graphics.setFont(fontMonth);
    }
 
    /**
     * 文字垂直
     */
    public static void drawSecondString(Graphics textGraphics, String text, int number) {
 
        // 每列顯示的漢字?jǐn)?shù)量
        int columnSize = number;
        // 文字之間的垂直間距
        int verticalSpacing = columnSize == 15 ? -500 : 50;
        // 獲取字體渲染上下文
        FontMetrics fm = textGraphics.getFontMetrics();
        // 獲取字體的高度
        int fontHeight = fm.getHeight();
 
        // 計(jì)算每列的寬度
        int columnWidth = columnSize == 15 ? 60 : fontHeight + verticalSpacing;
 
        // 設(shè)置初始位置
        int x = 0;
        int y = 0;
        switch (number) {
            case 3:
                x = 1100;
                y = 200;
                break;
            case 10:
                x = 1000;
                y = 210;
                break;
            case 15:
                x = 800;
                y = 210;
                break;
            // 可以添加更多的條件分支
            default:
                // 默認(rèn)情況下的坐標(biāo)設(shè)置
                break;
        }
        if (number == 10) {
            Font fontFour = new Font(text, Font.BOLD, 60);
            textGraphics.setFont(fontFour);
            textGraphics.setColor(Color.WHITE);
        } else if (number == 15) {
            Font fontFour = new Font(text, Font.BOLD, 40);
            textGraphics.setFont(fontFour);
            textGraphics.setColor(Color.WHITE);
        }
        // 繪制文字
        for (int i = 0; i < text.length(); i++) {
 
            char ch = text.charAt(i);
            // 計(jì)算當(dāng)前位置
            int cx = x - (i / columnSize) * columnWidth;
            int cy = y + (i % columnSize) * fontHeight;
 
            textGraphics.drawString(String.valueOf(ch), cx, cy);
        }
    }
 
}

業(yè)務(wù)代碼

首先新建3個(gè)目錄用來存放一下固定的背景圖片和 臨時(shí)的文件

generatePosterTemplate.java

 @Override
    public Map<String, Object> generatePosterTemplate(PosterTemplateDto template) throws IOException {
        // 首先讀取文件的路徑
        String imagesPath = new File("src/main/resources/").getAbsolutePath() + "/static/imagesFirst/";
        String imagesPathSecond = new File("src/main/resources/").getAbsolutePath() + "/static/imagesSecond/";
        String imagesPathLogo = new File("src/main/resources/").getAbsolutePath() + "/static/imagesLogo/";
        String temp = new File("src/main/resources/").getAbsolutePath() + "/static/temp/";
 
        // 創(chuàng)建顏色并設(shè)置透明度
        Map<String, Color> map = new HashMap<>();
        map.put("0", new Color(0, 88, 38));
        map.put("1", new Color(40, 50, 112));
        map.put("2", new Color(129, 2, 3));
        Color color = map.getOrDefault(template.getPosterColor(), new Color(0, 88, 38));
        Map<String, Object> fileMap = new HashMap<>();
        String fileName = IdUtil.simpleUUID().substring(0, 10) + DateTimeUtils.stringTime();
 
        PosterTemplateDto posterTemplate = "0".equals(template.getId())
                ? createPosterTemplate(template) : template;
        try {
            // 讀取背景圖片
            if ("0".equals(template.getPosterId())) {
                // 橫向海報(bào)
                // 讀取海報(bào)背景圖片    BufferedImage backgroundImage = ImageIO.read(new File("D:\\test1\\backImage.png"));
                File originalBackFile = new File(StrUtil.isNotBlank(template.getPosterBackImage())
                        ? getUpdatePhotoPath(imagesPathLogo, template.getPosterBackImage(), 1372, 1978) : imagesPath + "backImage.png");
                BufferedImage backgroundImage = ImageIO.read(originalBackFile);
                if (StrUtil.isNotBlank(template.getPosterBackImage())) {
                    // 將保存到本地的圖片名稱返回給我
                    fileMap.put("backImage", template.getPosterBackImage());
                }
 
                int alpha = 180; // 透明度(取值范圍:0 - 255)
 
                // 創(chuàng)建 Graphics2D 對象
                Graphics2D g2d = backgroundImage.createGraphics();
 
                // 設(shè)置透明度
                AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) alpha / 255);
                g2d.setComposite(alphaComposite);
 
                // 設(shè)置背景色
                g2d.setColor(color);
 
                // 填充整個(gè)圖片區(qū)域
                g2d.fillRect(0, 0, backgroundImage.getWidth(), backgroundImage.getHeight());
 
                // 讀取要貼的第一張小圖片 "D:\\test1\\schoolLogo.png"
                File originalFile = new File(imagesPath + "schoolLogo.png");
                BufferedImage image = ImageIO.read(originalFile);
                // 調(diào)用 resizeImageOne 方法進(jìn)行放大
                BufferedImage overlayImage1 = PosterUtil.scaleImage(image, 200, 90);
 
                // 讀取要貼的第二張小圖片
                BufferedImage overlayImage2 = ImageIO.read(new File(StrUtil.isNotBlank(template.getPosterLogo())
                        ? getUpdatePhotoPath(imagesPathLogo, template.getPosterLogo(), 670, 66) : imagesPath + "collegeLogo.png"));
                if (StrUtil.isNotBlank(template.getPosterLogo())) {
                    // 將保存到本地的圖片名稱返回給我
                    fileMap.put("logo", template.getPosterLogo());
                }
 
                // 讀取要貼的第三張小圖片
                BufferedImage overlayImage3 = ImageIO.read(new File(imagesPath + "erweima.png"));
 
                // 讀取頭像圖片
                BufferedImage avatarImage = ImageIO.read(new File(imagesPath + "touxiang.png"));
 
                // 縮小第五張圖片并裁剪成圓形
                BufferedImage scaledCircularAvatar = PosterUtil.resizeAndClipToCircle(avatarImage, 400);
 
                // 計(jì)算貼圖位置
                // 在背景圖片上貼上第一張圖片
                createImage(backgroundImage, overlayImage1, 50, 60);
                // 在背景圖片上貼上第二張圖片
                createImage(backgroundImage, overlayImage2, 280, 70);
                // 在背景圖片上貼上第三張圖片
                createImage(backgroundImage, overlayImage3, 50, 1200);
                // 在背景圖片上貼上縮小并且裁剪成圓形后的頭像圖片
                createImage(backgroundImage, scaledCircularAvatar, 790, 800);
                // 在圖片上寫字
                // TODO 創(chuàng)建Graphics對象
                Graphics2D graphics = backgroundImage.createGraphics();
 
                // 設(shè)置第一行字體和顏色:添加海報(bào)主題文字
                Font font = new Font("", Font.BOLD, 50);
                graphics.setFont(font);
                graphics.setColor(Color.WHITE);
                graphics.drawString(posterTemplate.getPosterTopic(), 50, 280);
 
                // 設(shè)置第二行的字體和顏色
                // TODO 添加第二行文字
                Font fontTwo = new Font("", Font.BOLD, 140);
                graphics.setFont(fontTwo);
                graphics.setColor(Color.WHITE);
                PosterUtil.drawWordAndLineFeed(graphics, fontTwo, posterTemplate.getPosterTitle(), 45, 480, 1200);
 
 
                // TODO 添加第三行文字 具體地址文字
                Font fontThree = new Font("", Font.BOLD, 65);
                graphics.setFont(fontThree);
                graphics.setColor(Color.WHITE);
                graphics.drawString(posterTemplate.getPosterAddress(), 43, 1800);
 
                // TODO 添加第四行文字 校區(qū) 地址文字
                Font fontFour = new Font("", Font.BOLD, 45);
                graphics.setFont(fontFour);
                graphics.setColor(Color.WHITE);
                graphics.drawString(posterTemplate.getPosterSchool(), 48, 1870);
 
                //主講人
                PosterUtil.drawString(graphics, "主講人", 3);
                PosterUtil.drawString(graphics, posterTemplate.getPosterMainSpeaker(), 10);
 
                // TODO 1.18 日期
                Font fontDate = new Font("", Font.BOLD, posterTemplate.getPosterMonth().length() == 4 ? 150 : 120);
                graphics.setFont(fontDate);
                graphics.setColor(Color.WHITE);
                graphics.drawString(posterTemplate.getPosterMonth(), 135, 900);
 
                // TODO  14:30 ~ 15:30  (周四)
                Font fontMinutes = new Font("", Font.BOLD, 60);
                graphics.setFont(fontMinutes);
                graphics.setColor(Color.WHITE);
                PosterUtil.drawWordAndLineFeed(graphics, fontMinutes, posterTemplate.getPosterDay(), 50, 970, 350);
 
                // TODO 添加海報(bào)的文字日期 2024 年份
                int yearX = 55; // 文字起始位置 x 坐標(biāo)
                int yearY = 930; // 文字起始位置 y 坐標(biāo)
                Font yearFont = new Font("", Font.BOLD, 50);
                // 設(shè)置渲染提示以獲得更好的質(zhì)量
                graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 
                // 創(chuàng)建一個(gè) AffineTransform 對象,并將其設(shè)置為順時(shí)針旋轉(zhuǎn)90度
                AffineTransform at = new AffineTransform();
                at.setToRotation(Math.PI / 2.0, yearX, yearY);
 
                // 應(yīng)用 AffineTransform 對象
                graphics.setTransform(at);
 
                // 獲取字體渲染上下文
                FontRenderContext frc = graphics.getFontRenderContext();
                // 獲取文本寬度
                int textWidth = (int) graphics.getFont().getStringBounds(posterTemplate.getPosterYear(), frc).getWidth();
 
                // 調(diào)整起始位置,以確保文本在旋轉(zhuǎn)后完全可見
                yearX -= textWidth;
                graphics.setFont(yearFont);
                // 繪制文字
                graphics.drawString(posterTemplate.getPosterYear(), yearX, yearY);
 
                // 釋放Graphics對象
                graphics.dispose();
                InsertMinio(temp, backgroundImage, fileName, fileMap);
            } else {
                // 豎向 排版海報(bào)
                // 讀取背景圖片 getUpdatePhotoPath(imagesPathLogo, template.getPosterLogo(), 670, 66)
                File originalBackFile = new File(StrUtil.isNotBlank(template.getPosterBackImage())
                        ? getUpdatePhotoPath(imagesPathLogo, template.getPosterBackImage(), 1472, 2102) : imagesPathSecond + "backImageSecondTwo.png");
                if (StrUtil.isNotBlank(template.getPosterBackImage())) {
                    // 將保存到本地的圖片名稱返回給我
                    fileMap.put("backImage", template.getPosterBackImage());
                }
                BufferedImage backgroundImage = ImageIO.read(originalBackFile);
                // 創(chuàng)建顏色并設(shè)置透明度
                int alpha = 240; // 透明度(取值范圍:0 - 255)
                // 創(chuàng)建 Graphics2D 對象
                Graphics2D g2d = backgroundImage.createGraphics();
 
                // 設(shè)置透明度
                AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) alpha / 255);
                g2d.setComposite(alphaComposite);
                // 設(shè)置左上角背景色
                g2d.setColor(color);
                // 填充整個(gè)圖片區(qū)域
                g2d.fillRect(0, 0, 450, 230);
                // 設(shè)置背景色
                Graphics2D g3d = backgroundImage.createGraphics();
                // 設(shè)置最下面的背景色
                g3d.setColor(color);
                // 填充整個(gè)圖片區(qū)域
                g3d.fillRect(0, 1980, backgroundImage.getWidth(), 230);
                // 讀取要貼的第一張小圖片
                File originalFile = new File(imagesPathSecond + "schoolImageLogo.png");
                BufferedImage image = ImageIO.read(originalFile);
                // 調(diào)用 resizeImageOne 方法進(jìn)行放大
                int width = 280;
                int height = 230;
                BufferedImage overlayImage1 = PosterUtil.scaleImage(image, width, height);
 
                // 讀取要貼的第二張小圖片
                BufferedImage overlayImage2 = ImageIO.read(new File(imagesPathSecond + "back2.png"));
 
                // 讀取要貼的第三張小圖片
                Map<String, Object> hashMap = new HashMap<>();
                hashMap.put("0", "green.png");
                hashMap.put("1", "blue.png");
                hashMap.put("2", "red.png");
                BufferedImage overlayImage3 = ImageIO.read(new File(imagesPathSecond + hashMap.getOrDefault(template.getPosterColor(), "green.png")));
 
                BufferedImage overlayImage4 = ImageIO.read(new File(imagesPathSecond + hashMap.getOrDefault(template.getPosterColor(), "green.png")));
                // 讀取頭像圖片
                BufferedImage avatarImage = ImageIO.read(new File(imagesPathSecond + "touxiang.png"));
                // 讀取二維碼
                File erweima = new File(imagesPathSecond + "erweima.png");
                BufferedImage erweimalogo = ImageIO.read(erweima);
                BufferedImage erweimaLogo = PosterUtil.scaleImage(erweimalogo, 200, 200);
 
                // 縮小第六張圖片并裁剪成圓形
                BufferedImage scaledCircularAvatar = PosterUtil.resizeAndClipToCircle(avatarImage, 400);
 
                // 讀取學(xué)校logo
                File schoolLogo = new File(imagesPathSecond + "schoolLogo.png");
                BufferedImage logo = ImageIO.read(schoolLogo);
                // 調(diào)用 resizeImageOne 方法進(jìn)行放大
                BufferedImage imageLogo = PosterUtil.scaleImage(logo, 200, 100);
 
                // 讀取學(xué)院logo getUpdatePhotoPath(imagesPathSecond, template.getPosterLogo(), 1472, 2102) 440 118
 
                // 讀取學(xué)院logo
                BufferedImage images;
                if (StrUtil.isNotBlank(template.getPosterLogo())) {
                    File collegeLogo = new File(getUpdatePhotoPath(imagesPathLogo, template.getPosterLogo(), 200, 100));
                    if (StrUtil.isNotBlank(template.getPosterLogo())) {
                        // 將保存到本地的圖片名稱返回給我
                        fileMap.put("logo", template.getPosterLogo());
                    }
                    images = ImageIO.read(collegeLogo);
                } else {
                    File collegeLogos = new File(imagesPathSecond + "collegelogos.png");
                    BufferedImage collegeImage = ImageIO.read(collegeLogos);
                    // 調(diào)用 resizeImageOne 方法進(jìn)行放大
                    images = PosterUtil.scaleImage(collegeImage, 200, 100);
                }
 
                // 讀取白色圓圈
                File yuan = new File(imagesPathSecond + "yuan.png");
                BufferedImage yuanImage = ImageIO.read(yuan);
                // 調(diào)用 resizeImageOne 方法進(jìn)行放大
                BufferedImage imagesYuan = PosterUtil.scaleImage(yuanImage, 450, 450);
 
                // 計(jì)算貼圖位置  X,Y
                // 在背景圖片上貼上第一張圖片
                createImage(backgroundImage, overlayImage1, -5, 5);
                // 在背景圖片上貼上第二張圖片
                createImage(backgroundImage, overlayImage2, 0, 230);
                // 在背景圖片上貼上第三張圖片
                createImage(backgroundImage, overlayImage3, 50, 1400);
                //在背景圖片上貼上第四張圖片
                createImage(backgroundImage, overlayImage4, 50, 1580);
                // 在背景圖片上貼上縮小并且裁剪成圓形后的頭像圖片
                createImage(backgroundImage, scaledCircularAvatar, 950, 370);
                //在背景圖片上貼上第六張圖片
                createImage(backgroundImage, erweimaLogo, 50, 1750);
                //在背景圖片上貼上第7張圖片
                createImage(backgroundImage, imageLogo, 900, 1990);
                //在背景圖片上貼上第8張圖片
                createImage(backgroundImage, images, 1200, 1990);
                //在背景圖片上貼上第9張圖片
                createImage(backgroundImage, imagesYuan, 925, 345);
                // 保存合成后的背景圖片
                // TODO 標(biāo)題
                Graphics2D graphics = backgroundImage.createGraphics();
 
                // TODO 添加第二行文字
                Font fontTwo = new Font("", Font.BOLD, 50);
                graphics.setFont(fontTwo);
                graphics.setColor(Color.WHITE);
                String posterTopic = posterTemplate.getPosterTopic();
//        drawWordAndLineFeed(graphics, fontTwo, textTwo, twoX, twoY, 320);
                PosterUtil.drawCenteredText(graphics, posterTopic, 100, 180);
                // TODO 主講人信息
                PosterUtil.drawSecondString(graphics, "主講人", 3);
                PosterUtil.drawSecondString(graphics, posterTemplate.getPosterMainSpeaker(), 10);
 
                // TODO 主講人詳細(xì)介紹信息
                PosterUtil.drawMyLectureString(graphics, posterTemplate.getPosterPeopleDetail());
                // 設(shè)置字體和顏色
                Font font = new Font("宋體", Font.PLAIN, 50);
                g2d.setFont(font);
                g2d.setColor(Color.BLACK);
                // 繪制豎排文字
 
                // TODO 講座名稱
                PosterUtil.drawMyString(graphics, posterTemplate.getPosterTitle(), color);
 
                //TODO 時(shí)間 2024
                Font fontYear = new Font("Source Han Sans CN", Font.PLAIN, 40);
                graphics.setColor(Color.BLACK);
                PosterUtil.qinxie(fontYear, graphics);  //字體傾斜
                graphics.drawString(posterTemplate.getPosterYear(), 50, 1480);
 
 
                //TODO 時(shí)間 月份 10.23  1.23
                Font fontMonth = new Font("Source Han Sans CN", Font.BOLD, 75);
                graphics.setColor(Color.BLACK);
                PosterUtil.qinxie(fontMonth, graphics);
                String posterMonth = posterTemplate.getPosterMonth();
                graphics.drawString(posterMonth, posterMonth.length() == 5 ? 210 : 250, 1480);
 
                //TODO 具體時(shí)間  20:12 ~ 11:00  周五
                Font fontDate = new Font("Source Han Sans CN", Font.PLAIN, 40);
                graphics.setColor(Color.BLACK);
                PosterUtil.qinxie(fontDate, graphics);
                graphics.drawString(posterTemplate.getPosterDay(), 50, 1550);
 
                // TODO 具體舉辦地點(diǎn)
                Font fontDd = new Font("", Font.BOLD, 35);
                graphics.setFont(fontDd);
                graphics.setColor(Color.BLACK);
                PosterUtil.qinxie(fontDd, graphics);
                PosterUtil.drawWordAndLineFeed(graphics, fontDd, posterTemplate.getPosterAddress(), 50, 1630, 330);
 
                // TODO 主持人
                Font zcr = new Font(" Source Han Sans CN", Font.PLAIN, 40);
                graphics.setColor(Color.white);
                graphics.setFont(zcr);
                String zcrName = "主持人: " + posterTemplate.getMainPeople();
                graphics.drawString(zcrName, 50, 2060);
 
                // 設(shè)置抗鋸齒
                graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                graphics.dispose();
                return InsertMinio(temp, backgroundImage, fileName, fileMap);
            }
        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
        return fileMap;
    }
public void createImage(BufferedImage backgroundImage, BufferedImage imagesYuan, int x, int y) {
        Graphics2D graphics9 = backgroundImage.createGraphics();
        graphics9.drawImage(imagesYuan, x, y, null);
        graphics9.dispose();
    }
 
    public Map<String, Object> InsertMinio(String temp, BufferedImage backgroundImage, String fileName, Map<String, Object> fileMap) throws Exception {
        File file = new File(temp);
        ImageIO.write(backgroundImage, "PNG", file);
        // 創(chuàng)建 FileInputStream 流
        FileInputStream inputStream = new FileInputStream(file);
 
        // 現(xiàn)在你可以使用 inputStream 進(jìn)行操作
        minioUtil.uploadInputStream("mpbucket", "sjs/wdjz/hbgl" + SLASH_SUFFIX + fileName + ".png", inputStream);
        InputStream download = minioUtil.download("mpbucket", "sjs/wdjz/hbgl" + SLASH_SUFFIX + fileName + ".png");
        // 將刪除的圖片文件保存到本地
        String name = fileName + ".png";
        byte[] bytes = IOUtils.toByteArray(download);
        String encoded = Base64.getEncoder().encodeToString(bytes);
        fileMap.put("posterTemplate", name);
        fileMap.put("code", BASE_64 + encoded);
        // 記得關(guān)閉流
        inputStream.close();
        // 刪除臨時(shí)文件
        file.delete();
        return fileMap;
    }
 
    /**
     * 修改圖片尺寸
     *
     * @return 新的海報(bào)地址
     */
    public String getUpdatePhotoPath(String path, String fileName, int width, int height) throws Exception {
        File originalFile = new File(path + fileName);
        byte[] originalImageData = Files.readAllBytes(originalFile.toPath());
        byte[] resizedImageData = FileUtil.resizeImage(originalImageData, width, height);
        // 將 byte[] 轉(zhuǎn)換為 ByteArrayInputStream
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(resizedImageData);
        // 創(chuàng)建臨時(shí)文件(如果需要)
        File tempFile = File.createTempFile("temp", ".tmp");
        // 將 ByteArrayInputStream 中的數(shù)據(jù)寫入臨時(shí)文件
        IOUtils.copy(byteArrayInputStream, Files.newOutputStream(tempFile.toPath()));
        // 使用臨時(shí)文件創(chuàng)建 FileInputStream
        FileInputStream fileInputStream = new FileInputStream(tempFile);
        // 現(xiàn)在你可以使用 fileInputStream 對象進(jìn)行操作
        minioUtil.uploadInputStream("mpbucket", "sjs/wdjz/hbgl" + SLASH_SUFFIX + fileName, fileInputStream);
        InputStream download = minioUtil.download("mpbucket", "sjs/wdjz/hbgl" + SLASH_SUFFIX + fileName);
        // 將保存的logo 圖片文件保存到本地
        FileUtil.convertInputStreamToFile(download, fileName);
        // 刪除 minio中的圖片
        minioUtil.deleteFile("mpbucket", fileName);
        // 關(guān)閉流和刪除臨時(shí)文件
        fileInputStream.close();
        tempFile.delete();
        return path + fileName;
    }
    //寫死兩個(gè)模板所需要的參數(shù)
    public PosterTemplateDto createPosterTemplate(PosterTemplateDto oldDto) {
        if ("0".equals(oldDto.getPosterId())){
            oldDto.setPosterTopic("物理與天文學(xué)院學(xué)術(shù)報(bào)告 第359期");
            oldDto.setPosterTitle("MIMO天線及其空口測試技術(shù)");
            oldDto.setPosterYear("2024");
            oldDto.setPosterMonth("10.18");
            oldDto.setPosterDay("14:30 ~ 15:30(周四)");
            oldDto.setPosterAddress("電信樓101講學(xué)廳");
            oldDto.setPosterSchool("中山大學(xué)(東校園)");
            oldDto.setPosterMainSpeaker("歐陽上官");
        } else {
            oldDto.setPosterTopic("逸仙生命講壇人第五十九講");
            oldDto.setPosterTitle("時(shí)空相分離調(diào)控的職務(wù)細(xì)胞信號(hào)轉(zhuǎn)導(dǎo)");
            oldDto.setPosterYear("2024");
            oldDto.setPosterMonth("1.23");
            oldDto.setPosterDay("20:12 ~ 11:00  周五");
            oldDto.setPosterAddress("中山大學(xué)(東校園)-電信樓101講學(xué)廳");
            oldDto.setPosterMainSpeaker("歐陽上官");
            oldDto.setPosterPeopleDetail("我啥事打卡機(jī)大街上的情況為其較為氣溫氣溫其味無窮我的撒登記卡水電氣網(wǎng)紅,誒打算近期我后端數(shù)據(jù)啊按地區(qū)為背景墻網(wǎng)格袋安山東劃算的揮灑的企鵝企鵝群。");
            oldDto.setMainPeople("李劍鋒");
        }
        return oldDto;
    }

到此這篇關(guān)于Java基于Graphics2D實(shí)現(xiàn)海報(bào)制作的文章就介紹到這了,更多相關(guān)Java Graphics2D海報(bào)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Jmeter正則表達(dá)式提取器實(shí)現(xiàn)過程圖解

    Jmeter正則表達(dá)式提取器實(shí)現(xiàn)過程圖解

    這篇文章主要介紹了Jmeter正則表達(dá)式提取器實(shí)現(xiàn)過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java實(shí)現(xiàn)圖片裁剪功能的示例詳解

    Java實(shí)現(xiàn)圖片裁剪功能的示例詳解

    這篇文章主要介紹了如何利用Java實(shí)現(xiàn)圖片裁剪功能,可以將圖片按照自定義尺寸進(jìn)行裁剪,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-01-01
  • 利用Java Set 去除重復(fù)object的方法

    利用Java Set 去除重復(fù)object的方法

    下面小編就為大家?guī)硪黄肑ava Set 去除重復(fù)object的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-01-01
  • mybatis的大于小于號(hào)轉(zhuǎn)義符號(hào)一覽

    mybatis的大于小于號(hào)轉(zhuǎn)義符號(hào)一覽

    這篇文章主要介紹了mybatis的大于小于號(hào)轉(zhuǎn)義符號(hào)一覽,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringAI流式輸出的底層實(shí)現(xiàn)原理解析

    SpringAI流式輸出的底層實(shí)現(xiàn)原理解析

    在 Spring AI 中,流式輸出(Streaming Output)是一種逐步返回 AI 模型生成結(jié)果的技術(shù),允許服務(wù)器將響應(yīng)內(nèi)容分批次實(shí)時(shí)傳輸給客戶端,而不是等待全部內(nèi)容生成完畢后再一次性返回,這篇文章主要介紹了SpringAI流式輸出的底層實(shí)現(xiàn),需要的朋友可以參考下
    2025-04-04
  • MyBatis在SQL語句中如何獲取list的大小

    MyBatis在SQL語句中如何獲取list的大小

    這篇文章主要介紹了MyBatis在SQL語句中如何獲取list的大小問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • java 中多線程生產(chǎn)者消費(fèi)者問題詳細(xì)介紹

    java 中多線程生產(chǎn)者消費(fèi)者問題詳細(xì)介紹

    這篇文章主要介紹了java 中多線程生產(chǎn)者消費(fèi)者問題詳細(xì)介紹的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • Java實(shí)現(xiàn)數(shù)據(jù)庫圖片上傳功能詳解

    Java實(shí)現(xiàn)數(shù)據(jù)庫圖片上傳功能詳解

    這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)數(shù)據(jù)庫圖片上傳功能,包含從數(shù)據(jù)庫拿圖片傳遞前端渲染,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-03-03
  • Java?中很好用的數(shù)據(jù)結(jié)構(gòu)EnumSet

    Java?中很好用的數(shù)據(jù)結(jié)構(gòu)EnumSet

    這篇文章主要介紹了Java?中很好用的數(shù)據(jù)結(jié)構(gòu)EnumSet,EnumMap即屬于一個(gè)Map,下文圍繞主題展開詳細(xì)內(nèi)容,需要的小伙伴可以參考參考一下
    2022-05-05
  • 詳解Mybatis攔截器安全加解密MySQL數(shù)據(jù)實(shí)戰(zhàn)

    詳解Mybatis攔截器安全加解密MySQL數(shù)據(jù)實(shí)戰(zhàn)

    本文主要介紹了Mybatis攔截器安全加解密MySQL數(shù)據(jù)實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01

最新評論