首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME 實用圖形工具類:文本自動換行、半透明渲染與灰度圖生成

     編輯:J2ME

前言:解決 J2ME 繪圖 API 的功能缺失

MIDP Graphics 類缺乏文本自動換行、Alpha 混合、顏色空間轉換等高級功能。本文提供三個生產級工具方法,已在多個商業手遊項目中驗證,直接可集成到項目中。

一、智能文本換行引擎 clipString()

功能特性

  • 支持指定像素寬度自動換行
  • 識別 \n 強制換行、\t 縮進(兩個漢字寬度)
  • 英文單詞不拆分(按空格/標點斷詞)
  • 中日韓字符逐字換行
  • 返回 String[] 供逐行繪製

核心實現


public static final String[] clipString(String str, Font font, int rowMaxW) {
    if (str == null) return null;
    // 最小寬度保護:至少容納一個漢字
    if (rowMaxW < font.charWidth('哈')) rowMaxW = font.charWidth('哈');

    Vector lines = new Vector();
    int strID = 0, rowW = 0;
    char ch;

    while (str.length() > strID) {
        ch = str.charAt(strID);
        switch (ch) {
            case '\n': // 顯式換行
                lines.addElement(str.substring(0, strID));
                str = str.substring(strID + 1);
                rowW = 0; strID = 0;
                break;
            case '\t': // 縮進展開為 6 個空格
                StringBuffer sb = new StringBuffer(str);
                sb.deleteCharAt(strID);
                sb.insert(strID, "      ");
                str = sb.toString();
                break;
            default: // 普通字符寬度累加
                if (rowW + font.charWidth(ch) > rowMaxW) {
                    lines.addElement(str.substring(0, strID));
                    str = str.substring(strID);
                    rowW = 0; strID = 0;
                } else {
                    rowW += font.charWidth(ch);
                    strID++;
                }
        }
    }
    lines.addElement(str); // 最後一行
    String[] result = new String[lines.size()];
    lines.copyInto(result);
    return result;
}

配套繪製方法


public static final void drawClipString(Graphics g, String[] lines, Font font, int color, int x, int y) {
    if (lines == null) return;
    g.setFont(font);
    g.setColor(color);
    int lineH = font.getHeight();
    for (int i = 0; i < lines.length; i++) {
        g.drawString(lines[i], x, y + i * lineH, Graphics.TOP | Graphics.LEFT);
    }
}

使用示例


String dialog = "歡迎來到冒險島!\n\t請選擇你的職業:\n1. 劍士  2. 法師  3. 弓箭手";
String[] lines = clipString(dialog, Font.getDefaultFont(), 160);
drawClipString(g, lines, Font.getDefaultFont(), 0x000000, 10, 10);

二、半透明圖片生成 alfImage()(需 MIDP 2.0)

原理

通過像素級 ARGB 操作,將原圖 Alpha 通道乘以指定透明度係數(0-10 級),生成新 Image 對象。

實現代碼


public static final Image alfImage(Image src, int alphaLevel) {
    if (src == null) return null;
    if (alphaLevel < 0) alphaLevel = 0;
    else if (alphaLevel > 10) alphaLevel = 10;

    int w = src.getWidth(), h = src.getHeight();
    int[] rgb = new int[w * h];
    src.getRGB(rgb, 0, w, 0, 0, w, h);

    // 計算 Alpha 掩碼:alphaLevel/10 * 255 << 24 | 0x00FFFFFF
    int alphaMask = ((alphaLevel * 255 / 10) << 24) | 0x00FFFFFF;

    for (int i = 0; i < rgb.length; i++) {
        rgb[i] &= alphaMask; // 保留 RGB,修改 Alpha
    }
    return Image.createRGBImage(rgb, w, h, true);
}

應用場景

  • 菜單背景模糊遮罩(alphaLevel=3~5)
  • 彈窗陰影層(alphaLevel=7)
  • 按鈕按下態疊加半透明遮罩
  • 淡入淡出動畫關鍵幀生成

三、灰度圖轉換 grayImage()

標準亮度公式(ITU-R BT.601)

GRAY = (R × 77 + G × 151 + B × 28 + 128) >> 8 —— 整數運算近似 0.299R + 0.587G + 0.114B

實現代碼


public static final Image grayImage(Image src) {
    if (src == null) return null;
    int w = src.getWidth(), h = src.getHeight();
    int[] rgb = new int[w * h];
    src.getRGB(rgb, 0, w, 0, 0, w, h);

    for (int i = 0; i < rgb.length; i++) {
        int pixel = rgb[i];
        int alf = (pixel >> 24) & 0xFF;
        int r = (pixel >> 16) & 0xFF;
        int g = (pixel >> 8) & 0xFF;
        int b = pixel & 0xFF;
        int gray = (r * 77 + g * 151 + b * 28 + 128) >> 8;
        rgb[i] = (alf << 24) | (gray << 16) | (gray << 8) | gray;
    }
    return Image.createRGBImage(rgb, w, h, true);
}

應用場景

  • 遊戲「石化/冰凍」狀態特效
  • 禁用狀態按鈕/圖標自動生成
  • 懷舊風格濾鏡
  • 減色壓縮預處理(灰度圖壓縮率更高)

性能與內存優化建議

  1. 緩存生成結果:半透明/灰度圖生成涉及像素循環,屬於重操作,必須在初始化階段預生成緩存
  2. 避免在 paint() 中調用:嚴禁每幀實時生成
  3. 釋放源圖引用:生成目標圖後,若源圖不再使用,置 null 協助 GC
  4. 內存峰值控制:大圖處理時,rgb[] 數組佔用 w*h*4 字節,注意分塊處理或複用數組

總結

這三個工具方法彌補了 MIDP 繪圖 API 的關鍵短板,配合離屏緩衝技術,可實現媲美原生應用的視覺效果。建議封裝為 GraphicsUtil 靜態類,作為項目基礎庫長期維護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved