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

J2ME 圖片高效翻轉實現:逐行像素運算避免大內存分配

     編輯:J2ME

背景與動機

MIDP 1.0 無翻轉 API,MIDP 2.0 雖有 Image.createImage(src, transform) 但廠商實現常有 Bug。一次性 getRGB 整圖入大陣列易致 OOM。逐行處理:每次僅分配一行寬度 int[],極限內存安全。

八種標準變換常量(兼容 MIDP 2.0 定義)

TRANS_NONE            = 0;
TRANS_ROT90           = 5;  // 顺时针 90
TRANS_ROT180          = 3;
TRANS_ROT270          = 6;
TRANS_MIRROR          = 2;  // 水平鏡像
TRANS_MIRROR_ROT90    = 7;
TRANS_MIRROR_ROT180   = 1;
TRANS_MIRROR_ROT270   = 4;

核心演算法:getRGB 取行 → 可選 arrayExchange 逆序 → drawRGB 寫目標行

public static Image transformImage(Image src, int transform) {
    int w = src.getWidth(), h = src.getHeight();
    Image dst = null;
    int[] line = new int[w];                 // 單行緩衝,復用
    Graphics g;

    switch (transform) {
        case TRANS_NONE:
            return src;

        case TRANS_ROT90:   // 目標 h×w,源行 i → 目標列 h-1-i
            dst = Image.createImage(h, w);
            g = dst.getGraphics();
            for (int i = 0; i < h; i++) {
                src.getRGB(line, 0, w, 0, i, w, 1);
                g.drawRGB(line, 0, 1, h - i - 1, 0, 1, w, true);
            }
            break;

        case TRANS_ROT180:  // 目標 w×h,源行 i 逆序 → 目標行 h-1-i
            dst = Image.createImage(w, h);
            g = dst.getGraphics();
            for (int i = 0; i < h; i++) {
                src.getRGB(line, 0, w, 0, i, w, 1);
                arrayExchange(line);         // 原地逆序
                g.drawRGB(line, 0, w, 0, h - 1 - i, w, 1, true);
            }
            break;

        case TRANS_ROT270:  // 目標 h×w,源行 i 逆序 → 目標列 i
            dst = Image.createImage(h, w);
            g = dst.getGraphics();
            for (int i = 0; i < h; i++) {
                src.getRGB(line, 0, w, 0, i, w, 1);
                arrayExchange(line);
                g.drawRGB(line, 0, 1, i, 0, 1, w, true);
            }
            break;

        case TRANS_MIRROR:  // 目標 w×h,源行逆序 → 同行
            dst = Image.createImage(w, h);
            g = dst.getGraphics();
            for (int i = 0; i < h; i++) {
                src.getRGB(line, 0, w, 0, i, w, 1);
                arrayExchange(line);
                g.drawRGB(line, 0, w, 0, i, w, 1, true);
            }
            break;

        case TRANS_MIRROR_ROT90:   // 鏡像+90:源行逆序 → 目標列 h-1-i
            dst = Image.createImage(h, w);
            g = dst.getGraphics();
            for (int i = 0; i < h; i++) {
                src.getRGB(line, 0, w, 0, i, w, 1);
                arrayExchange(line);
                g.drawRGB(line, 0, 1, h - i - 1, 0, 1, w, true);
            }
            break;

        case TRANS_MIRROR_ROT180:  // 鏡像+180:源行順序 → 目標行 h-1-i
            dst = Image.createImage(w, h);
            g = dst.getGraphics();
            for (int i = 0; i < h; i++) {
                src.getRGB(line, 0, w, 0, i, w, 1);
                g.drawRGB(line, 0, w, 0, h - 1 - i, w, 1, true);
            }
            break;

        case TRANS_MIRROR_ROT270:  // 鏡像+270:源行順序 → 目標列 i
            dst = Image.createImage(h, w);
            g = dst.getGraphics();
            for (int i = 0; i < h; i++) {
                src.getRGB(line, 0, w, 0, i, w, 1);
                g.drawRGB(line, 0, 1, i, 0, 1, w, true);
            }
            break;
    }
    return dst;
}

// 原地逆序,O(w/2)
public static final void arrayExchange(int[] a) {
    for (int i = 0, n = a.length - 1, half = a.length >> 1; i < half; i++) {
        int tmp = a[i];
        a[i] = a[n - i];
        a[n - i] = tmp;
    }
}

關鍵點總結

  • 單行緩衝 int[w] 復用,峰值內存 O(寬度) 而非 O(面積)
  • 利用 Graphics.drawRGB 參數 scanlength=1 實現「寫單列/單行」
  • 鏡像變換統一由 arrayExchange 完成,邏輯清晰
  • 兼容 MIDP 1.0/2.0,規避廠商 Bug,工程落地性極強
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved