圖片翻轉本質上是依照特定規則重新排列像素點。水平翻轉處理每一欄,垂直翻轉處理每一列,是像素重排中最基礎的操作。本文提供完整可執行的 MIDlet 範例,將翻轉邏輯封裝為可重用方法,並示範如何在 Canvas 上繪製原圖、水平鏡像、垂直鏡像三種效果。
關鍵技巧:使用 Graphics.setClip() 限制繪製區域為單欄/單列,再配合 drawImage() 的座標偏移實現鏡像效果。
範例包含兩個類別:
package imageconvert;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class TestMIDlet extends MIDlet {
private Display display = null;
private ImageConvertCanvas canvas = null;
public void startApp() {
display = Display.getDisplay(this);
canvas = new ImageConvertCanvas();
display.setCurrent(canvas);
}
public void pauseApp() { }
public void destroyApp(boolean unconditional) { }
}
package imageconvert;
import javax.microedition.lcdui.*;
public class ImageConvertCanvas extends Canvas {
private Image img = null;
public ImageConvertCanvas() {
try {
img = Image.createImage("/leaf.png"); // 載入專案資源圖片
} catch (Exception e) { }
}
protected void paint(Graphics g) {
int color = g.getColor();
g.setColor(0xFFFFFF);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(color);
// 1. 繪製原圖
g.drawImage(img, 0, 0, Graphics.LEFT | Graphics.TOP);
// 2. 繪製水平翻轉 (原圖下方)
hConvert(g, img, 0, img.getHeight() + 5);
// 3. 繪製垂直翻轉 (水平翻轉下方)
vConvert(g, img, 0, img.getHeight() * 2 + 10);
}
/** 水平翻轉:左右鏡像 */
private void hConvert(Graphics g, Image img, int x, int y) {
if (img == null) return;
int w = img.getWidth();
int h = img.getHeight();
for (int i = 0; i < w; i++) {
// 設定剪裁區域為第 i 欄 (寬度 1)
g.setClip(x + i, y, 1, h);
// 繪製時 X 座標鏡像偏移:x - w + 2*i
g.drawImage(img, x - w + 2 * i, y, Graphics.LEFT | Graphics.TOP);
}
}
/** 垂直翻轉:上下鏡像 */
private void vConvert(Graphics g, Image img, int x, int y) {
if (img == null) return;
int w = img.getWidth();
int h = img.getHeight();
for (int i = 0; i < h; i++) {
// 設定剪裁區域為第 i 列 (高度 1)
g.setClip(x, y + i, w, 1);
// 繪製時 Y 座標鏡像偏移:y - h + 2*i
g.drawImage(img, x, y - h + 2 * i, Graphics.LEFT | Graphics.TOP);
}
}
}

畫面由上而下依序顯示:原始圖片、水平翻轉結果、垂直翻轉結果。
以水平翻轉為例,原圖寬度為 w,第 i 欄 (0-based) 對應鏡像位置為 w - 1 - i。程式中 drawImage 的 x 參數 x - w + 2*i 推導如下:
目標位置 = x + (w - 1 - i)
= x + w - 1 - i
= x - w + 2*i + (w - 1) // 因為 setClip 從 x+i 開始,需補償
實際程式簡化為 x - w + 2*i (配合 setClip 起始位置)
同理垂直翻轉 Y 座標計算 y - h + 2*i。
setClip(x+i, y, 1, h) 限制只繪製第 i 欄像素drawImage 以整張圖片為來源,但因剪裁區限制,只有目標欄位會被更新drawImage 的目標座標,將來源圖片對應欄位「移動」到鏡像位置註:本文核心內容參考自陳躍峰部落格,筆者對繪圖代碼進行修改優化,並提供完整 MIDlet 與圖片資源供直接執行測試。