2007/04/22(日) [n年前の日記]
#3 [iappli] PaletteImage について実験中
Palette から getEntry() で取り出した int を Integer.toHexString() で16進数表示したら、
なんとかなりそうな予感。後は画像のロード部分に処理を追加 or 別途ロード処理を作成、かしら。実機上で動かした際のヒープサイズや描画処理速度が懸念されそうではあるけど。
00ffffffff 00ffff0000 00ff00ff00 00ff0000ff 00ff010203 00ff800000 00ff008000 00ff000080 00ff00ffff 00ffff00ff 00ffffff00こんな感じの値に。おそらくは、
((謎値 & 0x0ff) << 24) | ((R & 0x0ff) << 16) | ((G & 0x0ff) << 16) | (B & 0x0ff)という感じ? 謎の値で 0x0ff が入ってるのが気になるけれど。もしかすると不透明度の情報なのかもしれない。ということでそんな感じに推測して実験ソースを。
/** * PalettedImage の表示テスト */ import java.io.InputStream; import javax.microedition.io.Connector; import com.nttdocomo.io.ConnectionException; import com.nttdocomo.ui.Canvas; import com.nttdocomo.ui.Dialog; import com.nttdocomo.ui.Display; import com.nttdocomo.ui.Graphics; import com.nttdocomo.ui.IApplication; import com.nttdocomo.ui.Image; import com.nttdocomo.ui.MediaImage; import com.nttdocomo.ui.MediaManager; import com.nttdocomo.ui.Palette; import com.nttdocomo.ui.PalettedImage; import com.nttdocomo.ui.PhoneSystem; public class TestPalettedImage extends IApplication { Main m = new Main(); public void start() { Display.setCurrent(m); m.exec(); } } final class Main extends Canvas { static final int FPS = 20; static final int SLEEP_VALUE = 1000 / FPS; static final int SCR_W = 240; static final int SCR_H = 240; private Graphics g = getGraphics(); private int waitTime; private long getTime; private int frameCounter; private int rootStep; private Image bgimg; private PalettedImage palimg; private Palette[] pal = new Palette[5 * 5]; private int btnStsInterrupt; // コンストラクタ public Main() { System.gc(); } // メイン public void exec() { waitTime = SLEEP_VALUE; // フレーム間隔 rootStep = 0; // バックライトON PhoneSystem.setAttribute(PhoneSystem.DEV_BACKLIGHT, PhoneSystem.ATTR_BACKLIGHT_ON); getTime = System.currentTimeMillis(); // メインループ while (true) { try { switch (rootStep) { case 0 : // init { // 背景画像をロード MediaImage image = MediaManager.getImage("resource:///3.gif"); try { image.use(); bgimg = image.getImage(); } catch (ConnectionException e) { image = null; displayDialog(Dialog.DIALOG_ERROR, "実行エラー", "BGイメージロード失敗。" + e); } // パレットを変える画像をロード try { // Connection con=Connector.open("resource:///testimg.gif",Connector.READ); // InputConnection incon=(InputConnection)con; // InputStream in = incon.openInputStream(); InputStream in = Connector.openInputStream("resource:///2.gif"); // パレットを設定できるイメージを生成 palimg = PalettedImage.createPalettedImage(in); in.close(); } catch (Exception e) { displayDialog(Dialog.DIALOG_ERROR, "Error", "パレットイメージロード失敗。" + e); } // パレットを取得 Palette p = palimg.getPalette(); // 色数取得 int colnum = p.getEntryCount(); // パレット値を表示してみる for (int i = 0; i < p.getEntryCount(); i++) { int argb = p.getEntry(i); String s = "0000000000000000" + Integer.toHexString(argb); String sb = s.substring(s.length() - 16); System.out.println(sb); } // 変化させるためのパレットオブジェクトを確保 for (int i = 0; i < pal.length; i++) { pal[i] = new Palette(colnum); } // 変化させるためのパレットを作成 for (int c = 0; c < pal.length; c++) { int v = c * 256 / (5 * 5); for (int i = 0; i < p.getEntryCount(); i++) { int argb = p.getEntry(i); int a = (argb >> 24) & 0x0ff; int r = (argb >> 16) & 0x0ff; int g = (argb >> 8) & 0x0ff; int b = argb & 0x0ff; r = r * (256 - v) / 256; g = g * (256 - v) / 256; b = b * (256 - v) / 256; argb = Graphics.getColorOfRGB(r, g, b, a); pal[c].setEntry(i, argb); } } rootStep++; } break; case 1 : // draw { g.lock(); // BG 描画 g.drawImage(bgimg, 0, 0); { int w = palimg.getWidth(); int h = palimg.getHeight(); int idx = 0; for (int y = 0; y < 5; y++) { for (int x = 0; x < 5; x++) { int dx = 16 + (w + 8) * x; int dy = 16 + (h + 8) * y; // パレットを変える palimg.setPalette(pal[idx]); // 描画 g.drawImage(palimg, dx, dy); idx++; } } } g.unlock(true); } break; } System.gc(); while (System.currentTimeMillis() < getTime + waitTime) Thread.yield(); getTime = System.currentTimeMillis(); frameCounter++; } catch (Exception e) { displayDialog(Dialog.DIALOG_ERROR, "実行エラー", "処理中に問題発生。" + e + " rootStep=" + rootStep); } } } // 画面描画 public void paint(Graphics g) { } // イベント通知処理 public void processEvent(int a_type, int a_param) { if (a_type == Display.KEY_PRESSED_EVENT) btnStsInterrupt |= (0x01 << a_param); } // エラー時のダイアログ表示 public void displayDialog(int type, String title, String str) { Dialog d = new Dialog(type, title); d.setText(str); d.show(); IApplication.getCurrentApp().terminate(); } }
なんとかなりそうな予感。後は画像のロード部分に処理を追加 or 別途ロード処理を作成、かしら。実機上で動かした際のヒープサイズや描画処理速度が懸念されそうではあるけど。
◎ 2007/04/23追加。 :
上のソースは問題ありな予感。本番用ソースに同じような記述をしたら色がおかしくなった。
[ ツッコむ ]
以上です。