IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 教你Java5分钟制作海报、彻底解决终端兼容性问题 -> 正文阅读

[移动开发]教你Java5分钟制作海报、彻底解决终端兼容性问题

教你Java5分钟制作海报、彻底解决终端兼容性问题

一、需求背景

? 我们经常在多终端应用开发中会遇到这样的需求:用户在浏览商品时觉得不错,希望分享给朋友。此时终端(安卓、苹果、H5等)生成一张精美的商品海报,通过微信或者其他途径分享给他人。也可能会遇到需求:制作个人名片打印出来或者分享给他人。效果大概是这样的:

在这里插入图片描述
也可能是这样

(上面的图都是我从网上临时找的,只做参考学习,避免广告已经做了部分处理。)

刚开始设计这个需求的时候,我们是在前端来完成的,即由安卓、IOS、H5、微信几个端的开发者自主实现功能。各端完成开发后发布到全网,很快就发现一些用户机型上出现了兼容性的问题(C端安卓机型有很多版本)。用户手机安卓版本从5.N到最新的版本、从ip6到最新款,最大跨度超10年,这种兼容性问题对我们来说无法预料。曾尝试使用的dom-to-image和html2canvas效果都不太理想,解决了白屏、跨域问题又遇到低版本不支持标签的问题…。一通折腾,最后我们决定在服务端将海报图片生成好,在终端直接显示图片。

二、用JAVA生成海报

从上面的三张海报,我随机抽到了《美女》图,作为今天演示效果。(在做此演示时并没有使用之前项目上的图,我也是首次照着图在开发)。

首先将海报分别为3类,背景图、其他图、文字、二维码。

如: 1-底图纯白,2-商品介绍图,3-头像 素材,4-“严选”字样的图素材,5-带色的二维码,6-标题、价格等文字,实际开发中根据视觉和美工给的图即可。

先上我完成的最终效果:

在这里插入图片描述

简单做一下,大概和视觉图差不多了, 虽然有点糙但足以表达到效果。

2.1 Easy Poster 易海报生成器

? 在开发海报过程中,我也找了不少资料,花费了较多时间,后来发现了Easy Poster的设计还是不错的。所以在开发结束以后,我对代码进行了重新整理完善:修复了一些问题,并增加了二维码功能,成为开箱即用的海报生成工具。

接下来,我将介绍一下如何用来快速的制作海报。

创建一个新的海报,只需要3步即可完成

  • 修改pom.xml添加依赖和打包过滤字体库。
  • 创建海报对象及配置相关属性。
  • 传入参数,生成海报

2.2修改pom.xml添加依赖和打包过滤字体库。

pom.xml

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <lombok.version>1.16.18</lombok.version>
    <hutool-all.version>5.7.19</hutool-all.version>
    <zxing.version>3.4.1</zxing.version>
    <testng.version>6.8.8</testng.version>
    <slf4j.version>1.7.13</slf4j.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    <!-- 二维码生成 -->
    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>core</artifactId>
        <version>${zxing.version}</version>
    </dependency>
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>${hutool-all.version}</version>
    </dependency>
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>${testng.version}</version>
        <scope>test</scope>
    </dependency>
</dependencies>
<!-- SpringBoot项目的maven项目引用的字体库font经过maven的filter,会破坏font文件的二进制文件格式 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <configuration>
                <nonFilteredFileExtensions>
                    <nonFilteredFileExtension>ttf</nonFilteredFileExtension>
                    <nonFilteredFileExtension>woff</nonFilteredFileExtension>
                    <nonFilteredFileExtension>woff2</nonFilteredFileExtension>
                </nonFilteredFileExtensions>
            </configuration>
        </plugin>
    </plugins>
</build>

*注意:我们海报用到了字体作为资源文件引入,在经过maven的filter,会破坏font文件的二进制文件格式 导致打包异常,此处要一定要注意。

2.3 创建海报对象及配置相关属性

CommodityPosterPojo.java

package com.naiqing.poster.demo;

import com.quaint.poster.annotation.PosterBackground;
import com.quaint.poster.annotation.PosterBarCodeCss;
import com.quaint.poster.annotation.PosterFontCss;
import com.quaint.poster.annotation.PosterImageCss;
import com.quaint.poster.core.abst.AbstractDefaultPoster;
import com.quaint.poster.core.dto.PosterBarcode;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Tolerate;

import java.awt.*;
import java.awt.image.BufferedImage;

/**
 * 〈商品分享海报元素及相关参数定义〉<br>
 *
 * @author naiqing
 * @Date 2022/1/21
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@EqualsAndHashCode(callSuper = true)
@Data
@Builder
public class CommodityPoster2Pojo extends AbstractDefaultPoster {

    /**
     * 背景图
     */
    @PosterBackground(width = 540, height = 868)
    private BufferedImage backgroundImage;

    /**
     * 商品图
     */
    @PosterImageCss(position = {0, 0}, width = 540, height = 614)
    private BufferedImage commodityImage;

    /**
     * 严选图标
     */
    @PosterImageCss(position = {16, 625}, width = 50, height = 28)
    private BufferedImage yanxuanImage;
    /**
     * 商品标题
     */
    @PosterFontCss(position = {16, 625}, size = 22, canNewLine = {1, 482, 2}, style = Font.BOLD)
    private String commodityTitle;

    /**
     * 特权价
     */
    @PosterFontCss(position = {16, 706}, size = 20, color = {247,23,61})
    private String vipPrice;
    /**
     * 原价
     */
    @PosterFontCss(position = {16, 742}, size = 15, color = {51, 51, 51}, delLine = true)
    private String oldPrice;

    /**
     * 头像
     */
    @PosterImageCss(position = {10, 780}, width = 55, height = 55, circle = true)
    private BufferedImage headImage;

    /**
     * 昵称
     */
    @PosterFontCss(position = {77, 788}, color = {85,85,85}, name = "腾祥爱情体细简", style = Font.BOLD)
    private String nickName;
    /**
     * 昵称下的描述
     */
    @PosterFontCss(position = {75, 813}, size = 15, color = {104,104,104}, name = "腾祥爱情体细简")
    private String nickDesc;


    /**
     * 二维码
     */
    @PosterBarCodeCss(position = {376, 695}, width = 130, height = 130, foreColor = {17,125,124})
    private PosterBarcode qrCode;

    /**
     * 二维码字
     */
    @PosterFontCss(position = {386, 833}, size = 20, color = {104,104,104}, center = true)
    private String qrCodeText;

    @Tolerate
    public CommodityPoster2Pojo() {
    }
}


此处定义了海报全部的元素,通过注解:背景图片PosterBackground、其他图片@PosterImageCss、字体

@PosterFontCss和二维码@PosterBarCodeCss,来配置位置、宽度等参数(更多参数可通过源码了解)。

@PosterBarCodeCss 二维码注解,只适用类PosterBarcodeDto

@PosterBackground 背景图片注解、@PosterImageCss,只适用类BufferedImage

@PosterFontCss文字注解,只适用类String

  • 如何快速得到x\y坐标和width\heigth尺寸

    正常来说,视觉稿给到我们开发的时候,页面上都是可以快速得到每个元素的位置和尺寸,但此处因为是从网上找到整图,所以只能自己动手了。

    此处我是通过ps打开图片,打开”窗口-信息“,可以查看到鼠标的坐标及圈选的尺寸,如下图可以快速得到各元素的位置:

在这里插入图片描述

2.5 传入参数,生成海报

1) 加载字体库

在此调用生成海报之前,我们要将用到的字体库放到项目中,比如说我这里用到了2个字体库:resources\fonts\simkai.ttfresources\fonts\TTAiQingXiJ_0.ttf

这里我要特别说明:如果不加载字体库在windows下也是可以直接使用的(会默认使用宋体),但是在将服务发布到服务器下Linux时所有中文都会乱码,因为Linux下并没有相应字体库。

2)生成海报

我用一个单元测试来实现海报生成调用示范,传入商品名称相关信息

package com.naiqing.poster.demo;

import com.quaint.poster.core.dto.PosterBarcode;
import com.quaint.poster.core.impl.PosterBarcodeImpl;
import lombok.SneakyThrows;
import org.testng.annotations.Test;

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

/**
 * 〈测试海报〉<br>
 *
 * @author naiqing
 * @Date 2022/1/22
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class CommodityPoster2Test {

    @SneakyThrows
    @Test
    public void testCreate() {
        //背景图,此处测试我是用的本地图,实际开发可换成网络获取图片(下面有示例)
        BufferedImage backgroundImage = ImageIO.read(new File("D:\\temp\\s_bg.jpg"));
        //商品主图
        BufferedImage commodityImage = ImageIO.read(new File("D:\\temp\\s_commodity.jpg"));
        //严选图标
        BufferedImage yanxuanImage = ImageIO.read(new File("D:\\temp\\s_yanxuan.jpg"));
        //头像
        BufferedImage headImage = ImageIO.read(new File("D:\\temp\\s_head.jpg"));
        //二维码logo
        BufferedImage qrLogo = headImage;
        //二维码内容
        String qrContent = "http://www.baidu.com";

        //全局默认字体(如果不将字体库资源引入,在windows下没问题,但linux没有默认的"宋体"会显示乱码)
        InputStream in1 = this.getClass().getResourceAsStream("/fonts/simkai.ttf");
        Font defaultFont = Font.createFont(Font.TRUETYPE_FONT, in1);
        //昵称显示的字体(此字体库是从网上下载的,非windows自带),使用时引用FontName字体名称即可(字体名称:双击字体库可以看到字体名称)
        InputStream in2 = this.getClass().getResourceAsStream("/fonts/TTAiQingXiJ_0.ttf");
        Font txin2 = Font.createFont(Font.TRUETYPE_FONT, in2);

        CommodityPoster2Pojo shareCommodityInfo = CommodityPoster2Pojo.builder()
                .backgroundImage(backgroundImage)
                .commodityImage(commodityImage)
                .yanxuanImage(yanxuanImage)
                .commodityTitle("         雾中女孩2022冬季新款女装连帽拉链长袖棉服 WH88888")
                .vipPrice("特权价¥0.01")
                .oldPrice("售价¥268")
                .headImage(headImage)
                .nickName("叫我胡歌啊")
                .nickDesc("邀请好友享受内部优惠价")
                .qrCode(PosterBarcode.builder().content(qrContent).logo(qrLogo).build())
                .qrCodeText("微信扫一扫")
                .build();
        //创建海报生成器
        PosterBarcodeImpl<CommodityPoster2Pojo> poster = new PosterBarcodeImpl<>();
        //设置默认字体库  /安装用到的全部字体库(支持传多个)
        poster.defaultFont(defaultFont).installFonts(txin2,...);
        //生成海报
        BufferedImage image = poster.annotationDrawPoster(shareCommodityInfo).draw(null);
        ImageIO.write(image, "png", new File("D:\\temp\\out2.png"));
    }
}

可以看到用起来还是非常简单的,开箱即用!有了这个工具,5分钟可以搞一个海报出来!再也不需要去考虑APP端的不确定的兼容问题了,也不用兴师动众让安卓、苹果、H5等多端的开发者多人开发了。美滋滋~

我上面的示例是使用的本地图,也可以使用图片链接。

   //远程图片
   BufferedImage backgroundImage = ImageIO.read(new URL("https://img-blog.csdnimg.cn/8bf7094ae7b044f495035c8ea734dca8.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6LGB6L6-6aOO562d,size_18,color_FFFFFF,t_70,g_se,x_16"));
  • 如何使用自定义字体库?

? 当我们在制作海报时,视觉给的效果图可能除了颜色、粗体要求以外,可能还会要求使用指定的字体。此时我们要拿到此字体库文件”*.ttf“并放到项目资源目录下,比如我的是resources\fonts\*.ttf

? 第二步,是我们要得到此字体库的字体名称,在创建海报时配置@PosterFontCss 设置字体需要指定字体名称。双击此字体库文件,第一行就能看到字体名称,如下图:

在这里插入图片描述

  • 如何将海报图片转成base64返回给前端

    //将生成的海报图片以base64形式回写至终端
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    ImageIO.write(image, "png", stream);
    String asBase64 = "data:image/png;base64,"+Base64.encode(stream.toByteArray());
    System.out.println(asBase64);
    

三、 用到的技术及相关源码

3.1 Easy Poster 易海报生成器

? 以上的源码和示例代码均在gitee上,可直接下载。欢迎大家一起来修复完善此工具。
https://gitee.com/naiqing/easyposter

在此特别感谢框架Easy Poster 的作者,我是基于此框架,修复了一些问题后进行的二次开发。

3.3 二维码生成zxing

对于二维码的生成我是使用了谷歌的zxing,然后利用hutool-all来简化调用。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-25 10:42:32  更:2022-01-25 10:43:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:48:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码