偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

游戲賬號(hào)大圖生成

開(kāi)發(fā) 架構(gòu)
轉(zhuǎn)轉(zhuǎn)游戲賬號(hào)業(yè)務(wù)中,以王者榮耀為例,用戶(hù)關(guān)注的核心指標(biāo)是:英雄總數(shù)、皮膚總數(shù)、特色皮膚等重點(diǎn)信息。但是在舊版商品列表展示的圖片,是用戶(hù)上傳的圖片,以及一些簡(jiǎn)單業(yè)務(wù)規(guī)則生成的圖片,沒(méi)有突出賬號(hào)相關(guān)重點(diǎn)特色。

1 背景

2 從前端生成大圖,到后端生成大圖

2.1 前端生成大圖的考量與實(shí)現(xiàn)方案

2.2 前端生成大圖遇到的問(wèn)題及原因分析

2.3 改進(jìn)方案-后端生成大圖

3. 后端生成大圖的具體實(shí)現(xiàn)

3.1 Java圖像處理api

3.2 基礎(chǔ)信息部分

3.3 模塊化拼接皮膚分類(lèi)部分

4 總結(jié)

4.1 性能提升

4.2 用戶(hù)體驗(yàn)

4.3 擴(kuò)展性與維護(hù)性

1.背景

轉(zhuǎn)轉(zhuǎn)游戲賬號(hào)業(yè)務(wù)中,以王者榮耀為例,用戶(hù)關(guān)注的核心指標(biāo)是:英雄總數(shù)、皮膚總數(shù)、特色皮膚等重點(diǎn)信息。但是在舊版商品列表展示的圖片,是用戶(hù)上傳的圖片,以及一些簡(jiǎn)單業(yè)務(wù)規(guī)則生成的圖片,沒(méi)有突出賬號(hào)相關(guān)重點(diǎn)特色。

圖片圖片

雖然在商詳(商品詳情頁(yè))內(nèi)部已經(jīng)呈現(xiàn)出了完整的驗(yàn)號(hào)報(bào)告,但是用戶(hù)需要從商列(商品列表頁(yè))點(diǎn)擊進(jìn)入到商詳,存在較長(zhǎng)的轉(zhuǎn)換路徑,降低了關(guān)鍵信息的觸達(dá)效率。

圖片圖片

于是我們將游戲賬號(hào)相關(guān)重點(diǎn)信息生成大圖,展示在商列及商詳。

商列(商品列表頁(yè))大圖:

圖片圖片

商詳(商品詳情頁(yè))大圖:

圖片圖片

2.從前端生成大圖,到后端生成大圖

2.1 前端生成大圖的考量與實(shí)現(xiàn)方案

需求初期,大圖由前端生成,主要出于以下考慮:

  • 前端可利用瀏覽器原生渲染能力處理復(fù)雜布局和樣式,開(kāi)發(fā)驗(yàn)證速度較快。
  • 前端能更靈活地支持圖像處理,開(kāi)發(fā)成本較低。

前后端進(jìn)行交互,由后端提供生成圖片所需的全量物料圖片信息。前端拿到物料之后,通過(guò)頁(yè)面api,與Puppeteer截圖相結(jié)合的方式生成大圖。步驟如下:

  • 前端創(chuàng)建一個(gè)頁(yè)面,通過(guò)訪問(wèn)后端接口拿到對(duì)應(yīng)的物料數(shù)據(jù)(小圖url、文字等)。對(duì)這些圖片資源url數(shù)據(jù)進(jìn)行實(shí)時(shí)訪問(wèn),在頁(yè)面上進(jìn)行圖片與文字的繪制,進(jìn)而生成大圖的頁(yè)面。
  • 將此頁(yè)面的地址,傳到另一個(gè)Puppeteer服務(wù)。Puppeteer服務(wù)會(huì)啟動(dòng)一個(gè)瀏覽器實(shí)例,再次訪問(wèn)傳入的頁(yè)面,然后進(jìn)行截圖。

2.2 前端生成大圖遇到的問(wèn)題及原因分析

在上線之后,發(fā)現(xiàn)前端生成大圖會(huì)有一定概率的超時(shí)異常導(dǎo)致生成圖片失敗,平均2~3s,超時(shí)情況大于5s。在生成只有12個(gè)拼接圖片的情況下尚且超時(shí),隨著我們商詳大圖需求的引入,拼接圖片數(shù)量有時(shí)會(huì)超過(guò)600。此時(shí)超時(shí)情況會(huì)更加嚴(yán)重。

通過(guò)對(duì)整體鏈路的分析,發(fā)現(xiàn)Puppeteer服務(wù)截圖是一個(gè)耗時(shí)較多的操作,其大概步驟如下:

  • 申請(qǐng)服務(wù)內(nèi)存、磁盤(pán)等資源;
  • 創(chuàng)建瀏覽器進(jìn)程并啟動(dòng);
  • 通過(guò)網(wǎng)絡(luò)訪問(wèn)傳入頁(yè)面URL;
  • 渲染頁(yè)面并且進(jìn)行截圖。

2.3 改進(jìn)方案-后端生成大圖

為了解決前端方案的性能瓶頸,我們?cè)u(píng)估了遷移到后端生成圖片的可行性。對(duì)于上面遇到的問(wèn)題,后端可以有針對(duì)性地進(jìn)行解決:使用Java中awt包下的畫(huà)圖api拼接生成大圖,避免了Puppeteer啟動(dòng)瀏覽器、渲染頁(yè)面帶來(lái)的開(kāi)銷(xiāo)。

能否遷移到后端,有兩個(gè)衡量標(biāo)準(zhǔn),第一個(gè)是性能,即耗時(shí)。第二個(gè)是后端生成的圖片UI樣式,即能否達(dá)到UI驗(yàn)收標(biāo)準(zhǔn)。

于是我們先在本地測(cè)試,發(fā)現(xiàn)相同圖片耗時(shí)僅僅需要20ms左右(相較前端平均2~3秒的時(shí)間有較大提升)。即使涉及500多張圖片的拼接,平均耗時(shí)也只在2s左右。另外在生成的圖片樣式效果上也達(dá)到了UI驗(yàn)收的要求。

前端生成大圖:

圖片圖片

后端生成大圖:

圖片圖片

3. 后端生成大圖的具體實(shí)現(xiàn)

以上文提到的、規(guī)則相對(duì)復(fù)雜的商品詳情頁(yè)大圖為例進(jìn)行說(shuō)明。通過(guò)分析UI原型,我們發(fā)現(xiàn)其結(jié)構(gòu)具有清晰的模塊化特征:從上往下看依次為基礎(chǔ)信息模塊、分類(lèi)皮膚信息模塊。其中皮膚信息模塊又可分為分類(lèi)標(biāo)題模塊、單個(gè)皮膚單元模塊。

圖片圖片

這里需要用到的操作,包括繪制圖片、文字、伸縮圖片、平移圖片等。由于后端使用的編程語(yǔ)言為Java,所以先簡(jiǎn)要介紹一下Java圖片處理相關(guān)的api。

3.1 Java圖像處理api

在Java圖像處理中,java.awt.image.BufferedImage.BufferedImage與java.awt.Graphics2D是兩個(gè)核心類(lèi),它們密切協(xié)作以實(shí)現(xiàn)圖像的創(chuàng)建、編輯和渲染。

  • BufferedImage是圖像數(shù)據(jù)的畫(huà)布容器,負(fù)責(zé)存儲(chǔ)像素信息。主要用于讀寫(xiě)圖像文件。
  • Graphics2D是操作圖像的畫(huà)筆,負(fù)責(zé)繪制和修改圖像內(nèi)容。在BufferedImage上繪制內(nèi)容。支持繪制文字、圖像平移縮放等操作。

3.1.1 創(chuàng)建BufferedImage

/**
     * 讀取本地文件
     */
    BufferedImage imageFromFile = ImageIO.read(new File("本地圖片路徑"));
    /**
     * 從網(wǎng)絡(luò)中讀取圖片
     */
    BufferedImage imageFromUrl= ImageIO.read(new URL("網(wǎng)絡(luò)圖片路徑"));

    /**
     * 通過(guò)構(gòu)造方法創(chuàng)建。構(gòu)造參數(shù)指定寬和高。
    */
    BufferedImage combinedImage = new BufferedImage(100, 200, BufferedImage.TYPE_INT_RGB);

3.1.2 繪制圖片與文字

public static void main(String[] args) throws IOException {
        BufferedImage backGroundImage = ImageIO.read(new File("輸入路徑"));

        BufferedImage combinedImage = new BufferedImage(backGroundImage.getWidth(), backGroundImage.getHeight(), BufferedImage.TYPE_INT_RGB);

        Graphics2D graphics = combinedImage.createGraphics();
        try {
            // 畫(huà)圖
            graphics.drawImage(backGroundImage, 0, 0, null);
            // 寫(xiě)文字
            graphics.setFont(new Font("微軟雅黑", Font.BOLD, 20));
            graphics.setColor(Color.WHITE);
            graphics.drawString("文字內(nèi)容", 20, 20);

        } finally {
            // 釋放資源
            graphics.dispose();
        }

        // 保存結(jié)果
        File output = new File("輸出路徑");
        ImageIO.write(combinedImage, "jpg", output);
    }

3.1.3 圖片伸縮

public static void main(String[] args) throws IOException {
       // 伸縮前的畫(huà)面
        BufferedImage originImage = ImageIO.read(new File("文件路徑"));

        // 伸縮后的畫(huà)面
        BufferedImage scaleImage = getScaleImage(originImage, 0.7, 0.7);
        File output = new File("輸出路徑");
        ImageIO.write(scaleImage, "jpg", output);
 }

    /**
     * 對(duì)原始圖片按比例進(jìn)行伸縮
     */
    public static BufferedImage getScaleImage(BufferedImage originImage, double scaleFactorWidth, double scaleFactorHeight) {
        if (Objects.isNull(originImage) || scaleFactorWidth <= 0 || scaleFactorHeight <= 0) {
            return originImage;
        }
        // 等比例壓縮比例
        int scaledWidth = (int) (originImage.getWidth() * scaleFactorWidth);
        int scaledHeight = (int) (originImage.getHeight() * scaleFactorHeight);

        // 創(chuàng)建新的 BufferedImage
        BufferedImage scaledImage = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB);

        Graphics2D g2d = scaledImage.createGraphics();
        try {
            // 繪制縮放后的圖像
            g2d.drawImage(originImage, 0, 0, scaledWidth, scaledHeight, null);
        } finally {
            g2d.dispose();
        }
        return scaledImage;

3.2 基礎(chǔ)信息部分

原始UI圖如下,我們需要將具體文字信息寫(xiě)入到對(duì)應(yīng)位置內(nèi)。

圖片圖片

實(shí)現(xiàn)思路:

  • 首先將原始UI圖繪制到畫(huà)布;
  • 設(shè)置文字字體、大小,以及橫縱坐標(biāo)參數(shù),繪制文字。

效果圖如下:

圖片圖片

3.3 模塊化拼接皮膚分類(lèi)部分

皮膚分類(lèi)模塊分開(kāi)來(lái)看,可以按照皮膚類(lèi)型分成若干個(gè)大類(lèi),如史詩(shī)皮膚、限定皮膚等。同時(shí)在每個(gè)皮膚分類(lèi)模塊前有對(duì)應(yīng)標(biāo)題。

3.3.1 繪制標(biāo)題

通過(guò)api繪制標(biāo)題圖片到指定位置即可,這樣可省去字體設(shè)置與字體居中的步驟。

圖片圖片

3.3.2 生成皮膚圖片單元

每一個(gè)皮膚分類(lèi)中,各個(gè)皮膚單元都由四部分元素組成,分別是角標(biāo)圖片、底圖圖片、文字、浮層圖片。

圖片圖片

我們拿到這四部分基礎(chǔ)原始數(shù)據(jù)之后,按如下步驟進(jìn)行繪制:

  • 繪制皮膚底圖到畫(huà)布;
  • 繪制浮層覆蓋到皮膚底圖之上;
  • 繪制角標(biāo)圖片到指定位置;
  • 繪制文字到指定位置。

由于各類(lèi)小圖片信息是短時(shí)間內(nèi)不會(huì)變更的,所以這里會(huì)對(duì)各類(lèi)小圖片進(jìn)行本地緩存,避免頻繁網(wǎng)絡(luò)請(qǐng)求導(dǎo)致的資源浪費(fèi)。

3.3.3 生成皮膚分類(lèi)模塊

將所有生成的皮膚圖片單元按指定橫縱坐標(biāo)繪制。

圖片圖片

3.3.4 拉伸背景與邊框

原始UI切圖如下:

圖片圖片

由于每個(gè)賬號(hào)對(duì)應(yīng)的皮膚數(shù)量不同,需要讓背景圖與邊框適配對(duì)應(yīng)數(shù)量的皮膚圖片總高度。

圖片圖片

3.3.5 拼接生成各分類(lèi)組合大圖

通過(guò)對(duì)每個(gè)皮膚分類(lèi),重復(fù)以上步驟,即可生成各分類(lèi)組合大圖。

圖片圖片

4.總結(jié)

4.1 性能提升

生成耗時(shí)從平均2-3秒(前端+Puppeteer)降至毫秒級(jí)(簡(jiǎn)單圖片)至秒級(jí)(超復(fù)雜圖片如500+皮膚),解決了超時(shí)問(wèn)題。

4.2 用戶(hù)體驗(yàn)

確保了用戶(hù)在瀏覽商品時(shí),能快速地獲取到游戲賬號(hào)的核心價(jià)值信息。

4.3 擴(kuò)展性與維護(hù)性

通過(guò)模塊化思想,將圖片拼接的核心邏輯(圖片加載、繪制、文字渲染、布局、背景處理)抽象為可復(fù)用的基礎(chǔ)服務(wù)模塊。再結(jié)合動(dòng)態(tài)配置來(lái)定義不同游戲的大圖布局、元素樣式、數(shù)據(jù)映射規(guī)則等,實(shí)現(xiàn)了業(yè)務(wù)邏輯與渲染邏輯的解耦。使新游戲品類(lèi)的接入效率大幅提升。

現(xiàn)已應(yīng)用在王者榮耀、原神、火影忍者、槍?xiě)?zhàn)王者等多款游戲。

原神:

圖片圖片

火影忍者:圖片槍?xiě)?zhàn)王者:圖片

關(guān)于作者

張廉潔 轉(zhuǎn)轉(zhuǎn)Java開(kāi)發(fā)工程師

責(zé)任編輯:武曉燕 來(lái)源: 轉(zhuǎn)轉(zhuǎn)技術(shù)
相關(guān)推薦

2009-02-27 14:48:09

2009-10-23 14:50:28

游戲Windows 7兼容性

2022-10-11 16:34:28

深度學(xué)習(xí)模型

2009-03-19 01:26:00

2023-08-16 19:24:36

重構(gòu)

2014-08-27 10:57:09

2011-03-23 14:44:32

開(kāi)發(fā)者游戲Android

2021-07-07 19:29:15

微軟Windows 11Windows

2017-12-13 10:08:26

大數(shù)據(jù)圖數(shù)據(jù)推理數(shù)據(jù)科學(xué)

2015-09-21 13:17:55

免費(fèi)開(kāi)源游戲

2022-04-26 10:41:46

Android游戲開(kāi)發(fā)工具

2011-08-08 10:24:09

2009-06-09 10:13:46

賬號(hào)設(shè)置網(wǎng)絡(luò)控制

2023-09-07 20:33:08

2012-10-09 09:25:52

CPU制造過(guò)程硅晶片

2020-10-05 21:59:02

靜態(tài)網(wǎng)頁(yè)HTMLCSS

2011-11-17 14:00:54

2013-04-19 02:06:58

手機(jī)游戲手機(jī)游戲引擎技術(shù)選型

2011-11-24 09:55:22

iOS體育游戲應(yīng)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)