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);
}
grayImage()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);
}
null 協助 GCrgb[] 數組佔用 w*h*4 字節,注意分塊處理或複用數組這三個工具方法彌補了 MIDP 繪圖 API 的關鍵短板,配合離屏緩衝技術,可實現媲美原生應用的視覺效果。建議封裝為 GraphicsUtil 靜態類,作為項目基礎庫長期維護。