MIDP 1.0/2.0 均未提供圖片縮放 API,開發者需自行實現。本文介紹基於 Graphics.drawImage() 裁剪繪製的「雙通道單向插值」算法,並對比「雙重循環像素級複製」方案,量化性能差異給出工程選型建議。
將二維縮放分解為兩次一維操作:
newW × srcH 可變圖像,逐列從源圖按比例采樣繪製newW × newH 目標圖,逐行按比例采樣繪製利用 Graphics.setClip(x, y, w, h) 限制繪製區域為單行/單列,配合負座標偏移實現「源圖像素映射到目標像素」。
public static Image scale(Image src, int newW, int newH) {
int srcW = src.getWidth();
int srcH = src.getHeight();
// 1. 水平縮放
Image tmp = Image.createImage(newW, srcH);
Graphics g = tmp.getGraphics();
for (int x = 0; x < newW; x++) {
g.setClip(x, 0, 1, srcH); // 單列裁剪區
int srcX = x * srcW / newW; // 源圖對應列
g.drawImage(src, x - srcX, 0, Graphics.LEFT | Graphics.TOP);
}
// 2. 垂直縮放
Image dst = Image.createImage(newW, newH);
g = dst.getGraphics();
for (int y = 0; y < newH; y++) {
g.setClip(0, y, newW, 1); // 單行裁剪區
int srcY = y * srcH / newH; // 源圖對應行
g.drawImage(tmp, 0, y - srcY, Graphics.LEFT | Graphics.TOP);
}
return dst;
}
public static Image scale2(Image src, int newW, int newH) {
int srcW = src.getWidth(), srcH = src.getHeight();
Image dst = Image.createImage(newW, newH);
Graphics g = dst.getGraphics();
for (int x = 0; x < newW; x++) {
for (int y = 0; y < newH; y++) {
g.setClip(x, y, 1, 1); // 單像素裁剪
int srcX = x * srcW / newW;
int srcY = y * srcH / newH;
g.drawImage(src, x - srcX, y - srcY, Graphics.LEFT | Graphics.TOP);
}
}
return dst;
}
| 方案 | 繪製調用次數 | 耗時 | 相對性能 |
|---|---|---|---|
| scale() 雙通道 | newW + newH = 560 | ~60 ms | 1× (基準) |
| scale2() 雙重循環 | newW × newH = 76,800 | ~7,150 ms | ~119× 慢 |