public final static int TRANS_NONE = 0; // 無變化
public final static int TRANS_ROT90 = 5; // 順時針 90°
public final static int TRANS_ROT180 = 3; // 順時針 180°
public final static int TRANS_ROT270 = 6; // 順時針 270°
public final static int TRANS_MIRROR = 2; // 水平鏡像
public final static int TRANS_MIRROR_ROT90 = 7; // 鏡像 + 90°
public final static int TRANS_MIRROR_ROT180 = 1; // 鏡像 + 180°
public final static int TRANS_MIRROR_ROT270 = 4; // 鏡像 + 270°
public static Image transformImage(Image src, int transform) {
int srcW = src.getWidth();
int srcH = src.getHeight();
Image dest = null;
switch (transform) {
case TRANS_NONE:
return src;
case TRANS_ROT90: // 90°: (w,h) -> (h,w), 行變列,列逆序
dest = Image.createImage(srcH, srcW);
for (int y = 0; y < srcH; y++) {
src.getRGB(lineBuf, 0, srcW, 0, y, srcW, 1);
dest.getGraphics().drawRGB(lineBuf, 0, 1, srcH - y - 1, 0, 1, srcW, true);
}
break;
case TRANS_ROT180: // 180°: 尺寸不變,每行像素逆序,行順序逆序
dest = Image.createImage(srcW, srcH);
for (int y = 0; y < srcH; y++) {
src.getRGB(lineBuf, 0, srcW, 0, y, srcW, 1);
reverse(lineBuf); // 水平鏡像
dest.getGraphics().drawRGB(lineBuf, 0, srcW, 0, srcH - y - 1, srcW, 1, true);
}
break;
case TRANS_ROT270: // 270°: (w,h) -> (h,w), 行變列,列順序
dest = Image.createImage(srcH, srcW);
for (int y = 0; y < srcH; y++) {
src.getRGB(lineBuf, 0, srcW, 0, y, srcW, 1);
reverse(lineBuf);
dest.getGraphics().drawRGB(lineBuf, 0, 1, y, 0, 1, srcW, true);
}
break;
case TRANS_MIRROR: // 水平鏡像: 尺寸不變,每行像素逆序
dest = Image.createImage(srcW, srcH);
for (int y = 0; y < srcH; y++) {
src.getRGB(lineBuf, 0, srcW, 0, y, srcW, 1);
reverse(lineBuf);
dest.getGraphics().drawRGB(lineBuf, 0, srcW, 0, y, srcW, 1, true);
}
break;
case TRANS_MIRROR_ROT90: // 鏡像+90°
dest = Image.createImage(srcH, srcW);
for (int y = 0; y < srcH; y++) {
src.getRGB(lineBuf, 0, srcW, 0, y, srcW, 1);
reverse(lineBuf);
dest.getGraphics().drawRGB(lineBuf, 0, 1, srcH - y - 1, 0, 1, srcW, true);
}
break;
case TRANS_MIRROR_ROT180: // 鏡像+180° = 垂直鏡像
dest = Image.createImage(srcW, srcH);
for (int y = 0; y < srcH; y++) {
src.getRGB(lineBuf, 0, srcW, 0, y, srcW, 1);
dest.getGraphics().drawRGB(lineBuf, 0, srcW, 0, srcH - y - 1, srcW, 1, true);
}
break;
case TRANS_MIRROR_ROT270: // 鏡像+270°
dest = Image.createImage(srcH, srcW);
for (int y = 0; y < srcH; y++) {
src.getRGB(lineBuf, 0, srcW, 0, y, srcW, 1);
dest.getGraphics().drawRGB(lineBuf, 0, 1, y, 0, 1, srcW, true);
}
break;
default:
return src;
}
return dest;
}
private static final int[] lineBuf = new int[MAX_WIDTH]; // 靜態複用,避免頻繁分配
public static final void reverse(int[] arr) {
int len = arr.length;
for (int i = 0, j = len - 1; i < j; i++, j--) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
原圖: 目標 (ROT90):
1 2 3 4 9 5 1
5 6 7 8 --> 10 6 2
9 10 11 12 11 7 3
12 8 4
註釋中包含所有 8 種變換的像素映射圖,便於理解驗證。
lineBuf 靜態分配最大寬度,避免循環中頻繁 new int[] 觸發 GC。reverse() 原地交換,無額外內存。基於 Image.getRGB + Graphics.drawRGB 實現 8 種幾何變換,算法清晰、性能優化到位、兼容 Sprite 變換常量,是 J2ME 圖形處理的基礎工具類。