最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實現(xiàn)圖片合成的示例詳解

 更新時間:2022年01月19日 14:59:40   作者:溫故知新之java  
前端有一個神器——canvas,這個畫布標簽可以處理各種圖片的合成,可以精確到圖片的具體坐標。java后端也有這樣的神器,那就是image-combiner,可以很簡單的合成圖片,感興趣的可以試一試

場景

前端有一個神器——canvas,這個畫布標簽可以處理各種圖片的合成,可以精確到圖片的具體坐標,加水印,去水印,簡直不要太簡單!那java后端可以處理嗎?請大聲的告訴他,能,必須能!今天小編告訴你一個神器——image-combiner,合成圖片so easy!

環(huán)境

  • jdk1.8
  • spring boot

搭建

引入pom文件

<dependency>
    <groupId>com.freewayso</groupId>
    <artifactId>image-combiner</artifactId>
    <version>2.2.0</version>
</dependency>

定義核心接口ImageService

public interface ImageService {
    /**
     * 簡單圖片聚合
     * @param
     * @return void
     * @author liyajie
     * @createTime 2021/12/17 9:54
     **/
    InputStream generateSimpleImage(String text, String bgImageUrl, String todoImage, String localPath, Boolean saveLocal, Boolean saveOss);

    /**
     * 復雜圖片聚合
     * @param
     * @return void
     * @author liyajie
     * @createTime 2021/12/17 9:54
     **/
    InputStream generateComplexImage(String title, String content, String bgImageUrl, String qrCodeUrl, String productImageUrl, String waterMarkImageUrl, String avatarImageUrl, String localPath, Boolean saveLocal, Boolean saveOss);
}

定義核心接口實現(xiàn)類ImageServiceImpl

@Service
public class ImageServiceImpl implements ImageService {

    @Override
    public InputStream generateSimpleImage(String text, String bgImageUrl, String todoImage, String localPath, Boolean saveLocal, Boolean saveOss) {
        InputStream is = null;
        try{
            // 合成器(指定背景圖和輸出格式,整個圖片的寬高和相關(guān)計算依賴于背景圖,所以背景圖的大小是個基準)
            ImageCombiner combiner = new ImageCombiner(bgImageUrl, OutputFormat.JPG);
            // 加圖片元素,第二個參數(shù)是左邊界距,第三個參數(shù)是上邊距
            combiner.addImageElement(todoImage, 300, 300);
            // 加文本元素,第二個參數(shù)是字體大小,第三個參數(shù)是左邊界距,第四個參數(shù)是上邊距
            combiner.addTextElement(text, 60, 100, 960);
            // 執(zhí)行圖片合并
            combiner.combine();
            // 可以獲取流(并上傳oss等)
            is = combiner.getCombinedImageStream();
            // 保存到本地
            if(saveLocal){
                combiner.save(localPath);
            }
            // 保存到oss
            if(saveOss){
                // TODO: 2021/12/17 保存到oss
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return is;
    }

    @Override
    public InputStream generateComplexImage(String title, String content, String bgImageUrl, String qrCodeUrl, String productImageUrl, String waterMarkImageUrl, String avatarImageUrl, String localPath, Boolean saveLocal, Boolean saveOss) {
        InputStream is = null;
        try{
            BufferedImage waterMark = ImageIO.read(new URL(waterMarkImageUrl)); //水印圖
            BufferedImage avatar = ImageIO.read(new URL(avatarImageUrl));       //頭像
            //創(chuàng)建合成器(指定背景圖和輸出格式,整個圖片的寬高和相關(guān)計算依賴于背景圖,所以背景圖的大小是個基準)
            ImageCombiner combiner = new ImageCombiner(bgImageUrl, 1500, 0, ZoomMode.Height, OutputFormat.JPG);  //v1.1.4之后可以指定背景圖新寬高了(不指定則默認用圖片原寬高)

            //針對背景和整圖的設(shè)置
            combiner.setBackgroundBlur(30);     //設(shè)置背景高斯模糊(毛玻璃效果)
            combiner.setCanvasRoundCorner(100); //設(shè)置整圖圓角(輸出格式必須為PNG)

            //標題(默認字體為阿里普惠、黑色,也可以自己指定Font對象)
            combiner.addTextElement(title, 0, 150, 1400)
                    .setCenter(true)        //居中繪制(會忽略x坐標,改為自動計算)
                    .setAlpha(.8f)         //透明度(0.0~1.0)
                    .setRotate(45)         //旋轉(zhuǎn)(0~360)
                    .setColor(Color.red);    //顏色

            //內(nèi)容(設(shè)置文本自動換行,需要指定最大寬度(超出則換行)、最大行數(shù)(超出則丟棄)、行高)
            combiner.addTextElement(content, "微軟雅黑", 40, 150, 1480)
                    .setStrikeThrough(true)             //刪除線
                    .setAutoBreakLine(837, 2, 60);      //自動換行

            //商品圖(設(shè)置坐標、寬高和縮放模式,若按寬度縮放,則高度按比例自動計算)
            combiner.addImageElement(productImageUrl, 0, 160, 837, 0, ZoomMode.Width)
                    .setCenter(true)       //居中繪制(會忽略x坐標,改為自動計算)
                    .setRoundCorner(46);     //設(shè)置圓角

            //頭像(圓角設(shè)置一定的大小,可以把頭像變成圓的)
            combiner.addImageElement(avatar, 200, 1200)
                    .setRoundCorner(200);   //圓角

            //水?。ㄔO(shè)置透明度,0.0~1.0)
            combiner.addImageElement(waterMark, 630, 1200)
                    .setAlpha(.8f)         //透明度(0.0~1.0)
                    .setRotate(45)         //旋轉(zhuǎn)(0~360)
                    .setBlur(20);           //高斯模糊(1~100)

            //加入圓角矩形元素(版本>=1.2.0),作為二維碼的底襯
            combiner.addRectangleElement(138, 1707, 300, 300)
                    .setColor(Color.WHITE)
                    .setRoundCorner(50)     //該值大于等于寬高時,就是圓形,如設(shè)為300
                    .setAlpha(.8f);

            //二維碼(強制按指定寬度、高度縮放)
            combiner.addImageElement(qrCodeUrl, 138, 1707, 186, 186, ZoomMode.WidthHeight);

            //價格(元素對象也可以直接new,然后手動加入待繪制列表)
            TextElement textPrice = new TextElement("¥1290", 60, 230, 1300);
            textPrice.setColor(Color.red);          //紅色
            textPrice.setStrikeThrough(true);       //刪除線
            combiner.addElement(textPrice);         //加入待繪制集合

            //執(zhí)行圖片合并
            combiner.combine();

            //可以獲取流(并上傳oss等)
            is = combiner.getCombinedImageStream();

            //保存到本地
            if(saveLocal){
                combiner.save(localPath);
            }
            //保存到oss
            if(saveOss){
                // TODO: 2021/12/17 保存到oss
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return is;
    }
}

測試ImageController

@RestController
@Slf4j
public class ImageController {

    @Resource
    HttpServletResponse response;

    @Autowired
    ImageService imageService;

    /**
     * 簡單圖片聚合
     * @param
     * @return void
     * @author liyajie
     * @createTime 2021/12/17 10:43
     **/
    @GetMapping("/createSimpleImage")
    public void createSimpleImage(){
        OutputStream os = null;
        try {
            String text = "周末大放送";
            String bgImageUrl = "https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg";
            String todoImage = "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg";
            // 圖片流
            InputStream is = imageService.generateSimpleImage(text, bgImageUrl, todoImage,"",false,false);
            BufferedImage image = ImageIO.read(is);
            response.setContentType("image/png");
            os = response.getOutputStream();
            if (image != null) {
                ImageIO.write(image, "png", os);
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error("獲取圖片異常{}",e.getMessage());
        } finally {
            if (os != null) {
                try {
                    os.flush();
                    os.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 復雜圖片聚合
     * @param
     * @return void
     * @author liyajie
     * @createTime 2021/12/17 10:43
     **/
    @GetMapping("/createComplexImage")
    public void createComplexImage(){
        // 背景圖
        String bgImageUrl = "https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg";
        // 二維碼
        String qrCodeUrl = "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg";
        // 商品圖
        String productImageUrl = "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg";
        // 水印圖
        String waterMark = "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg";
        // 頭像
        String avatar = "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg";
        // 標題文本
        String title = "# 最愛的家居";
        // 內(nèi)容文本
        String content = "蘇格拉底說:“如果沒有那個桌子,可能就沒有那個水壺”";
        OutputStream os = null;
        try{
            // 圖片流
            InputStream is = imageService.generateComplexImage(title, content, bgImageUrl, qrCodeUrl, productImageUrl, waterMark, avatar,"",false,false);
            BufferedImage image = ImageIO.read(is);
            response.setContentType("image/png");
            os = response.getOutputStream();
            if (image != null) {
                ImageIO.write(image, "png", os);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (os != null) {
                try {
                    os.flush();
                    os.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
}

測試效果

總結(jié)

從測試效果可以看到:

  • 實現(xiàn)了圖片和圖片的合成
  • 實現(xiàn)了圖片和文字的合成
  • 圖片和文字的位置都可以使用參數(shù)來動態(tài)修改(具體可以看代碼)

以上就是Java實現(xiàn)圖片合成的示例詳解的詳細內(nèi)容,更多關(guān)于Java圖片合成的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • @Autowired注解在抽象類中失效的原因及解決

    @Autowired注解在抽象類中失效的原因及解決

    這篇文章主要介紹了@Autowired注解在抽象類中失效的原因及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • eclipse如何搭建Springboot項目詳解

    eclipse如何搭建Springboot項目詳解

    今天帶大家學習eclipse如何搭建Spring boot項目,文中有非常詳細的圖文解說,對正在學習java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • springsecurity實現(xiàn)用戶登錄認證快速使用示例代碼(前后端分離項目)

    springsecurity實現(xiàn)用戶登錄認證快速使用示例代碼(前后端分離項目)

    這篇文章主要介紹了springsecurity實現(xiàn)用戶登錄認證快速使用示例代碼(前后端分離項目),本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-03-03
  • mybatis返回key value map集合方式

    mybatis返回key value map集合方式

    這篇文章主要介紹了mybatis返回key value map集合方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Spring?cloud?Hystrix注解初始化源碼過程解讀

    Spring?cloud?Hystrix注解初始化源碼過程解讀

    這篇文章主要為大家介紹了Hystrix初始化部分,我們從源碼的角度分析一下@EnableCircuitBreaker以及@HystrixCommand注解的初始化過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2023-12-12
  • Spring Boot 中的 @ConditionalOnBean 注解場景分析

    Spring Boot 中的 @ConditionalOnBean 注解場景分析

    本文詳細介紹了Spring Boot中的@ConditionalOnBean注解的使用場景、原理和基本用法,通過多個示例,展示了如何使用該注解根據(jù)Bean是否存在來動態(tài)地注冊或跳過特定的Bean,感興趣的朋友一起看看吧
    2025-03-03
  • jasypt SaltGenerator接口定義方法源碼解讀

    jasypt SaltGenerator接口定義方法源碼解讀

    這篇文章主要為大家介紹了jasypt SaltGenerator接口定義方法源碼解讀,,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • SpringBoot輕松實現(xiàn)ip解析(含源碼)

    SpringBoot輕松實現(xiàn)ip解析(含源碼)

    IP地址一般以數(shù)字形式表示,如192.168.0.1,IP解析是將這個數(shù)字IP轉(zhuǎn)換為包含地區(qū)、城市、運營商等信息的字符串形式,如“廣東省深圳市 電信”,這樣更方便人理解和使用,本文給大家介紹了SpringBoot如何輕松實現(xiàn)ip解析,需要的朋友可以參考下
    2023-10-10
  • Serializable接口的作用_動力節(jié)點Java學院整理

    Serializable接口的作用_動力節(jié)點Java學院整理

    這篇文章主要為大家詳細介紹了java中Serializable接口的作用,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Java中static修飾的靜態(tài)變量、方法及代碼塊的特性與使用

    Java中static修飾的靜態(tài)變量、方法及代碼塊的特性與使用

    這篇文章主要介紹了Java中static修飾的靜態(tài)變量、方法及代碼塊的特性與使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04

最新評論

龙口市| 苍梧县| 谢通门县| 河北区| 当雄县| 林周县| 饶河县| 托克逊县| 太白县| 丰顺县| 铁力市| 商水县| 左权县| 洛宁县| 高要市| 沁水县| 车致| 舒兰市| 荣成市| 平度市| 龙岩市| 黄骅市| 昆明市| 兴和县| 蓬溪县| 抚顺市| 清镇市| 金乡县| 文安县| 界首市| 囊谦县| 尤溪县| 南宁市| 山东| 汤原县| 馆陶县| 柳河县| 钟祥市| 大方县| 石阡县| 黔南|